It doesn't need to be skeuomorphically constrained into a 'book' with cute page turning animations, and no ability to use a scroll wheel, shift-space to go back (looks like `space` is hardcoded in his script, but only works half the time), or any of the features you already have in a browser. (I wonder how accessible it is in a Screen Reader, too.)
Yea, except, Apple most definitely favors aesthetics over functionality.
Take the iPod shuffle:
- Gen 1 was minimal, usable, and a portable USB drive,
- Gen 2 was minimal and usable, but lost its portable USB drive functionality (required a cable to also be carried around), but
- Gen 3 was smaller for no reason, moved the controls to an earbud cable which was impossible to use while running, and cost extra to buy an adapter if you didn't want to use their shitty earbuds, and then
- Gen 4 returned to the 2nd Gen design, because Gen 3 was very clearly flawed.
Seriously, explain the 3rd Gen iPod Shuffle.
I can cite many examples where they've dumped functionality for aesthetics, like non-removable batteries, fully-sealed computers (latest Mac mini), etc, but this is the clearest mistake they've made where they had to actually reverse course because of their favoritism for aesthetics over functionality.
I'm not going to defend individual design choices as I wasn't party to the tradeoffs being considered - and I disagree with some of them myself. But if you are involved in any kind of design (and I would definitely include programming here), you will be well aware of how much goes into boiling down a set of compromises into something elegant and usable - and how hard it can be to communicate why some part of that was really the best choice and took a lot of deep thought and iteration to get there. And you'll also be aware that design is never finished.
More generally, Apple have taken what many might think of as an industrial design approach and applied it to consumer design in a more rigorous way than others. So a lot of thought about coatings and materials used for screens and bodies, packaging (part of the consumer experience), and so on.
To construct a plausible scenario around your point off the top of my head, reduced size is clearly a key functional feature of a portable device, and while I'm not defending 3rd gen shuffle, it would make sense that a device you might go running with would be better if absolutely tiny. And if you are on the run, there would be an argument for having controls on the cable rather than the device. I think these kinds of things are clearly getting a lot of attention as we see the designs are being iterated and previous mistakes corrected.
Likewise, things like sealed devices are absolutely functional design decisions from the point of view of creating a mass-produced device. The success of the ipad bears this out. It may appal me that apple will only completely swap an ipad with cracked screen, or that I can't upgrade RAM in my macbook - but I can understand that standardisation and non-customisation is key to things like a predictable user experience, manufacturing and supply chain, worldwide warranties. Apple have always been about this and it's why they manufacture both hardware and software. I won't buy the 12" macbook computing device myself, but for family members it might be the ideal laptop. Anything else and I know I'm going to get several more messages a week asking me why facebook and twitter aren't working.
This was the page that made me finally grasp why Lisp and s-expressions are relevant. After reading this about a year ago, I ended up picking up a Clojure book and now I'm enamored with s-expressions. I feel late to the party.
The last time I tried to learn Lisp (prior to reading this) was in like 2003/4 from some CLISP tutorial that scared me away from having nothing but math examples and zero explanation of the philosophy or design. It felt like an esoteric and purely academic language, and I brushed it off as not worth my time. (I was never really put off by the parens, and now I love them. Never understood that aspect of Lisp discourse. Once you learn ParEdit you don't want to go back.)
There's a "lisp parens lol" thing among programmers that's so intellectually lazy. I once interviewed someone who I noticed had explicitly mentioned Lisp on their resume, and when as an aside I asked what their thoughts on Lisp development were, all they could muster was "Oh god the parens hyuck hyuck".
Yeah that screen space, truly a limited resource. You should cram everything together and don't forget to be extra clever in the middle of the dense unreadable forest of sigils as well. It was hard to write, it should be hard to read.
While I agree that in programming we should break our code in logical paragraphs, just like in prose, such conventions (placing closing brackets on their own line) are detrimental for that purpose. For me this doesn't have anything to do with wasting vertical space, as it has to do with aesthetics.
I'm not really speaking for LISP, but in my projects what really bothers me are people that don't have common sense when indenting / formatting their code and so they start using IDE or build plugins, using common conventions and formatters that will never be able to understand the meaning of the code being formatted, making a total mess of other people' carefully crafted code. And we go round and round on this.
I don't know that it is intellectually lazy. It makes a lot of sense.
That's not the case with lisp dialects. The major payoff with lisp dialects is macros. But for most people, it isn't obvious why they are important. They are something you have to use to really get.
So the intellectually reasonable position for most people is to either ignore lisp or laugh at it. Meanwhile, you see endless articles like this posted over the years (not knocking the article itself), trying to explain lisp in a kind of reverence and terminology usually associated with religious texts. "Hey, brother, you just need to see the light".
I've been doing quite a bit of Clojure coding lately and I love it. I just can't see a lisp ever catching on. Actually, the project I'm working on is a lisp that does not look like a lisp but compiles down to Clojure. The parens aren't really necessary for lisp's best feature, as seen by Elixir. Here's a bit of my language:
I'm not saying being "pragmatic" in this way is "bad" or "wrong," and since this is pretty much a total derail, I'll stop engaging in this thread. But, like, this is the actual thing you said that I was responding to:
"the intellectually reasonable position for most people is to either ignore lisp or laugh at it"
I said that such a position has nothing to do with "intellectual reasonableness" because it's barely an intellectual position at all. There is no propositional content; there is very little thought involved at all; it's a default "meh" position that is more accurately labelled "laziness."
One should not sneer or laugh at languages like Perl, COBOL, or similar, simply because there are others we like better, or are more popular.
I used to be a HUGE Perl fan, and discounted Python for years. I figured that I already knew Java, and since Python and Perl were effectively similar, it was a waste of my time to study both. I now regret that. As formative as that was for my growth as a programmer, I've loved coding in Python more than almost any other language -- and I delayed that discovery by a decade because I wrote it off as "effectively the same as" Perl.
Sure, it was pragmatic to focus on one language that I was learning and using. But the reasons I did so were flawed, IMO.
the parens seems pretty necessary for that expression, I can't even tell what it's doing...
it's joining the vector 1,2,3 with a space to make "1 2 3 ", right? so what is that count doing there? I'm not saying that lists are the end all be all of syntax (clojure has vectors for a lot of things specifically to reduce the parens), but you need something there to make it clearer
I get what you are saying, but when you are talking about programming languages as opposed to math or another domain, more people are familiar or comfortable with the former, hence the reason for numerous posts like the original having to explain why lisp's syntax is a good thing.
I think most people have an irrational dislike of s-expressions, but that at the same time, s-expressions are not as good as their proponents think they are. There's a certain aesthetic "purity" to them that's seductive, but from a practical standpoint, it is quite reasonable to adapt syntax to common patterns. The issue with mainstream languages isn't that they do that, it's that they do it too much.
But there are syntactic schemes besides s-expressions that allow for good flexibility. For instance, in my programming language Earl Grey, I use this very simple sugar: `a b: c` <=> `a(b, c)`. So you can use this todo syntax if you want, and it will just work:
item priority(high): "Clean the house."
item priority(medium): "Wash the dishes."
item priority(medium): "Buy more soap."
Interestingly this has one advantage over s-expressions: whereas Lisp editors usually need to specify a special highlighting/indent policy for keywords like `let`, here editors can just highlight/indent `a b: c` indiscriminately.
I also think a limited number of infix operators are worth defining in most languages, and I don't mean arithmetic operators (although I'm okay with them). I mean ubiquitous or easily repurposed operators like assignment/declaration, lambda, pairing, or commas. In my view, Lisp-like languages hold to standards of purity that are unreasonable (don't get me wrong, they are quite usable, just not optimal according to any useful metric).
I would say there are too many distracting "tags" in that which may be unnecessary ("XML disease"). For instance, look how you just indicated with a tag that the elements of a list are "items". In Lisp!
(todo "name" (item ...) (item ...) (item ...)).
Basically the symbol todo is enough of a clue about the structure, and the pure syntax can determine most of the rest, with possibly a modicum of keywords here and there.
(todo housework ;; symbols for naming!
(:high "Clean the house")
(:medium "Wash the dishes")
(:medium "Buy more soap"))
S-expressions are not obvious "just by looking" either. Don't forget you had to learn what they were and how they worked. You know that `(a b c)` is a list of three elements, that the first element can be extracted with the `car` function, and the rest with `cdr`, and so on. You also know that `(a b)` is shorthand for `(a . (b . nil))`, which helps a lot in knowing how to manipulate it. The fact that you are already familiar with Lisp taints your perception.
Not to mention Lisps, especially the new ones, throw obviousness out the window with merry abandon. Let's look at Clojure. You think it's obvious how to operate on Clojure? Here: `(let [a 1, b 2] (+ a b))`. What is that? I've mostly coded in Scheme, I don't know what square brackets are supposed to do. Vectors? How do I manipulate them and what are they doing in my let? And what does the comma do? Oh, nothing? Then why is it there? And if the comma means nothing are you telling me that if I want to list the names that are being defined by this form, I need to extract the even-indexed elements of a vector? Sure I can do that, but don't tell me you care about ease of manipulation.
Anyway, sorry for the rant ;)
I think the point I really want to make here is that sure, s-expressions are quite simple, but if I can explain how s-expressions work in a minute, and how my expressions work in five minutes, this isn't really a matter of ease of manipulation, this is a matter of laziness. If a language's source-to-AST rules can be fully explained in one or two paragraphs or a small table, and can be easily remembered, then that's all that matters. I think that `a b: c` <=> `a(b, c)` is trivial enough that it does not have any meaningful impact on ease of manipulation.
For reference, an S-expression based syntax that could be used for this example:
(item :priority high "Clean the house.")
(item :priority medium "Wash the dishes.")
(item :priority medium "Buy more soap"))
Your syntax certainly has advantages, but one can easily prefer S-expressions in this case without appealing to vague values like "aesthetic purity," nor are there any blatantly obvious "practical" downsides to using a more fully parenthesized syntax.
Been recently studying Lisp/Scheme, and I couldn't help but relate these "Quantum Pairs" with cons cells and the relationship described as a tree data structure. (Not equating them here, just a musing of mine.)
Speaking of misfeatures: I was scrolling down this page, wanted to go back up to re-read something, and the entire page just changed.
I wondered why for a second, then made a half-inch swipe to the left and discovered there's a "feature" to let me change the page for some reason, but it requires that I change the fundamental way I operate my phone/browser.
Tried to read the article again, and on the way down to where I was last reading, the page changed again. Closed the tab and won't bother reading the rest because I'm infuriated.
This is on a Nexus 5 with Android 5.1, so no, there is no rendering issue here, or lag in read of inputs. This is just an anti-feature that need not exist, nor is made obvious to the user that it exists and needs to be worked around.
I've found need for a note taking mobile app recently, but after trying to use Keep and seeing that it has zero organizational tools such as tags or folders, I just started to use Evernote instead.
Frankly, it is nearly impossible to recommend Keep when Evernote exists. Until they have, at minimum, some way to organize notes, it's just a pile of notes sitting in one window. But it would still be a hard sell when compared to all the Evernote features, such as the desktop clients that allow you to take screenshots and annotate them.
Edit: Oh, and there's also Geeknote¹ for CLI usage, as well as Vim plugins².
If you disable the annotation tool popup after taking a screenshot in the settings, then yea, it creates a "Screen clip" note with the image immediately after you finish dragging the screenshot range. (Of course, you can annotate later.)
Google Wave was an XMPP-based protocol¹. It allowed communication and collaboration with revisioning. It could have been embedded into applications such as office suites, giving you collaboration and communication right inside the app.
Wave.google.com was an example product using said protocol. Since the protocol was barely spoken of, even by developers, everyone assumed the website was the (only) product. Since the website did a lot of things, and none of it well, often being compared to email, it flopped and the entire project folded..
Thank you so much for this reference. The moment I grokked Clojure, I immediately thought "someone should port this to LLVM". The JVM is awful in a thousand ways, and it is quite surprising to me that Rich Hickey would devote so much time to getting many details right but get this big one wrong.
As much as I don't like Clojure on top of the JVM, I don't think you can say that the man who created the 3rd seriously successful dialect of Lisp made a big mistake/
I count "mainline Lisp", which ended with Common Lisp, and Scheme as the other two; others might count Autodesk's and Gnu Emacs' embedded Lisps.
Clojure is even showing signs of becoming mainstream in a way no Lisp has been since mainline Lisp through sometime in the '80s, not counting Scheme's niches in language research and (temporary? one) education. Or perhaps even better.
I view the JVM choice as a pragmatic choice to encourage wider adoption rather than a technical choice. Possibly it eased implementation too having a high-quality GC, but overall the drawbacks are quite severe, because they outright preclude Clojure from being used in situations outside the "long-running server process" use case.
It is even possible that he viewed the JVM as a stopgap to be abstracted out when and if the language got popular. It seems they are moving in this direction with ClojureScript. Clearly he made this decision thoughtfully and consciously because he was an expert in C++ before he ever wrote a line of Clojure interpreter, and could have made it native if he wanted.
But the argument "Clojure is successful, therefore all his decisions must have been optimal" (caracaturing you a little bit) is obviously false. Replace "Clojure" with "Linux" or even "Windows" and you see the fallacy.