The Nature of Lisp (2006)
defmacro.org
defmacro.org
What is it with statements like this? It just sounds like a 'meme' to me, that everyone hears (even from advocates like this one) at first that the 'syntax' (of which there is a lot less than most languages in a Lisp) is 'horrible'?
Of course, we, the learn-ed of Lisp, say that after a while the 'parens just disappear', which they don't, but they sure help (when combined with Paredit) in defining code like structures that can be manipulated with ease in your editor.
I know the author is just trying to do a bit of a 'sandwich' with the article, but please, advocates and enemies of Lisp, just give up on picking on the parens. It's stupid and been done a million times. It's like 'why do we have to type so much to enter programs! such a pain!'.
Boring.
;; Make [] == ()
(set-syntax-from-char #\[ #\( )
(defun lbrace-reader (stream inchar)
(declare (ignore inchar))
(read-delimited-list #\] stream t))
(set-macro-character #\[ #'lbrace-reader)
(set-macro-character #\] (get-macro-character #\) ))
(set-syntax-from-char #\] #\) )Guile Scheme, for example:
scheme@(guile-user)> [list 1 2 3]
$1 = (1 2 3)
scheme@(guile-user)> (list 1 2 3)
$2 = (1 2 3)
scheme@(guile-user)> [car '[1 2 3]]
$3 = 1I only have a cursory familiarity with lisps but I constantly find that too easy to miss.
So I’m going to be against this.
> Apple does not provide a way to do these remappings on OS X
Run Emacs (or XEmacs) under XQuartz and you can do whatever remapping you want. This is how I deal with it.
Another choice is a fully programmable keyboard, though these also tend to have nonstandard layouts that require some retraining.
And unless you do need X, I suggest using Emacs-Mac-Port instead of of the official Emacs: https://bitbucket.org/mituharu/emacs-mac/overview
$ setxkbmap -option parens:swap_bracketsSo yes, while complaints about syntax are largely irrelevant once you already know the language, the complaints will be there for any new user.
If the person justifying Lisp doesn't mind that the word 'cons' is terrible, why should I trust their aesthetic sense about anything? If I have to have "miserable notations" to get "coding nirvana", and coding nirvana is so great, why not fix the notations? do you just think everyone should have to struggle because you did?
I guess it feels like trying to determine which of these statements are true: (1) "Lisp is coding nirvana" (2) "Lisp is weird regressive nostalgia for a simpler era where nothing was typed and everyone used Emacs and memorized arcane terminology and shared macros on Usenet", and there are way too many signs that it's a lot of (2).
[edited to be less abrasive]
whyknow thing like word"and"sentence to write and plural and capitalization comma dot semicolon space question mark need write spaces between them wordamabobs
why don't fix notation???
TBH, though, as someone who used to love Scheme (and has yet to spend any real time with Clojure), I agree that there's a hefty amount of nostalgia involved. 2 or 3 decades ago, lisp felt like a total sea change compared to what else was out there, which was mostly just a bunch of C and BASIC dialects. Nowadays even the C dialects have adopted most of what made lisp feel great, and I just don't feel that great a need to go back to living a world where (almost) everything is a linked list.
Oh please, cry me a river. Like monads, promises, or props are any better.
> If the person justifying Lisp doesn't mind that the word 'cons' is terrible, why should I trust their aesthetic sense about anything? If I have to have "miserable notations" to get "coding nirvana", and coding nirvana is so great, why not fix the notations? do you just think everyone should have to struggle because you did?
Your ignorance is baffling. The notation is a feature, not a bug. If you want the feature, then yes, you will have to struggle.
While cons and cdr as concepts are necessary to learning what goes underneath the hood, idiomatic lisp is rarely written in terms of cons and cdr.
(Monads and props are definitely not better. You won't find me defending them! 'Promise' is a much better name, though.)
Naming is important, but the core Lisp names can be learned in a day.
It is also used for non-list data structures.
Sometimes in CS education Lisp is/was used to teach new stuff, making sure that students were challenged beyond their comfort zones, for example by reinventing the basic machineries from a few abstract principles. Typically Lisp was not used as a programming language, but as a device to teach new ways to think about computation: algorithms, some basic data structures, control structures, functional programming, ... Today you'll see other langages in CS education, with other goals.
See SICP and others...
car and cdr are weirder, but there are reasons people use them over first and rest: 1- they are shorter and 2- they can be combined (caadr, cadr, cddr, instead for (first (rest x)) etc).
It is still bikeshedding. You learn that stuff in less time than what it takes to create an angry post.
And if you really hate them, you don't have to use them. Just define a macro and you can stop complaining. Your coworkers may not like this though.
So, what would be a better name than 'cons'? 'List' is not right; the empty list is not a cons. Scheme uses 'pair', which is admittedly not too bad, but I think it would be more appropriate for an immutable pair than a mutable two-element struct. (I actually think there should be two types, immutable pairs and mutable conses. In such a Lisp, conses would probably be fairly rarely used, and much more of a historical relic.)
And to echo what outworlder says, it really just isn't that big a deal. Yes, Common Lisp has some historical baggage, and a lot of things we would change if were designing our own Lisp from scratch — I assure you every Lisper has their own list. But CL rationalization projects, of which there have been several over the years (and, no doubt, more that I'm not aware of), don't catch on. The reason is clear: the CL community is already "small yet remarkably fragmented" as I recall someone putting it (Eric Raymond?); a rationalized CL would just fork off another sub-community, if it caught on at all.
> Your ignorance is baffling.
That is not acceptable on HN and will get you banned. Please read https://news.ycombinator.com/newsguidelines.html and only post with respect for others.
I agree with you about car, cdr, and Lisp notation—and that strengthens the sentence above. The last thing we want is people arguing for correct positions by being a jerk. By doing so you discredit what's correct and/or legitimize being a jerk—two dreadful outcomes that matter more than someone being wrong (in your view or mine) about car and cdr.
The same can be said about older languages like C, which also have standardized notations.
Why fix what isn't broken?
Renaming stuff every few years dosn't make it easier to learn.
Right...because `caddr' and `caaddr' are good because??? And when is the last time you consciously used any of those primitives?
Ok, so what do you think are better names for those operators and why would they be better?
Do I even need to justify why these are better names? The problem is not that people don't know about better names. Everyone does [0]. My issue is that this doesn't seem to bother people.
[0]: https://www.gnu.org/software/emacs/manual/html_node/eintr/St...
The Lisp practice for 40 years is to use FIRST, REST, LIST, APPEND, LIST*, ... when we speak about List Processing.
CONS, CAR and CDR are used when cons cells are used for things like trees, graphs and other data structures. It's an indicator that the code is very low-level and used for assembling other data structures from cons cells.
I sometimes use cons cells for binary trees - first and rest are misleading in that case. I very often use cons cells to define things - the car is some object and the cdr is some property or definition that applies to the object. first and rest are misleading for that use case.
What you are proposing is to use domain-specific names for operations on an abstract data structure. Any names with pre-existing meaning will become misleading as soon as the data structure is applied to a different application. Coming up with new terminology to unambiguously refer to new technical concepts is not a "problem," it is a means of effective communication.
This is not about aesthetics, unless you are arguing that the symbols should be replaced by square brackets or emoji.
And this has been tried before. S-Expressions are not the only way to express lisp. There are M-Expressions and many other notations. Even significant whitespace has been tried.
And yet people keep coming back to parentheses. Don't you think there is a reason for that?
Also: almost all other languages use the exact same convention for lists that Lisp uses (except they tend to use square brackets as their symbol).
Like they're really not. "first" and "rest" work just as well as car and cdr.
https://stackoverflow.com/questions/29907440/difference-betw...
"[edited to be less abrasive]"
Keep editing.
It's tricky online to find the right place in between "having opinions" and "never contributing". I have opinions about the Lisp world that aren't that nice but weren't represented in the comment section, so I wanted to throw them in. The opinions are dismissive, so they had to sound a bit dismissive. My first pass was overly dismissive so I edited it but I don't think I want to go more "o please teach me!" than I did because then I'm lying about how I (and I think other people!) feel. Which is, basically, frustrated.
(All things considered, I don't think that 'for' or 'switch' are any clearer, anyway.)
What really gets me? Semicolons. Most useless character in programming language history. Every time I switch from a language that doesn't require them to one that does, the pirates run away from me.
At least parentheses have a useful purpose and can even help you when writing code (paredit and the like). Semicolons are only there to help compiler writers.
It would be ok if they were allowed, but optional. How many times do you really have to write more than one statement per line?
Nice expression. Is it a pop culture reference I have missed?
Note that Lisp has taken the first approach: It's clear (by closing the opening paren) when you're done with a statement.
The artificial distinction between statements and expressions is a source of endless annoyance to me when I'm working (as I do, for my day job) in a language that has it. In Lisp I can say things like
(when (some (lambda (x) ...) some-list)
(do-something))
There, I've written a loop in the predicate of a conditional (the 'some' expression is true if the function passed to it returns true on any element of the list). Statement-oriented languages have generally not had an elegant way to do that, though admittedly that is changing somewhat, as lambda expressions and higher-order functionals become more popular.The point is, I think this complaint, about the statement/expression distinction, has a lot more substance than complaints about either parentheses or semicolons.
A statement can span multiple lines. And it has no termination marker.
You spend years learning that 2 + 2 = 4, seeing (+ 2 2) for the first time is a bit of a shock.
The point is overused but its a good point and he doesnt dwell on it. Arguments shouldnt be evaluated just by how interesting they are.
Tell me, what does this mean?
x = x + 5
Obviously, it's a null statement. It's nonsense. x cannot equal x + 5 because that means 0 = 5 and, therefore, 0 = 1 and, therefore, all mathematics is broken. However, most Algols are completely happy to accept that statement, something we learned was nonsensical way back in our childhoods, as not only valid but as the only way of doing things.My point is, there is no such thing as a natural syntax. They're all weird. They all have to be learned. Some provide more benefits than others after they've been learned.
(Also: You're only a newbie once. Optimizing for that one-time thing is a bit odd, when you'll spend far more of your life as an experienced programmer.)
You know, like how Scala/Scheme is a Lisp.
Each non-lisper will reinvent the argument from scratch, so advocates can't profitably ignore it. It's a shame. You get past that so quickly after using lisp.
So I tried once to use a dot as list terminator, which didn't work well. I found myself adding different terminators for each level of depth. Because, at some point the encapsulation over multiple levels leads to ambiguity, if outfix notation isn't used (as for the encapsulation in this sentence). A common wisdom is to avoid deep indentation. 3rd normal form schemes are enough for most cases, thank Codd.
By the way: I've been hugely interested in historical linguistics recently and came to conclude counting must have been a huge boost for the development of language facility. Basic phrases are just enumerations. Which reminded me of list processing. Many old languages actually tend to follow VSO word order, too. Plural is often enough expressed as reduplication. But I don't have deeper insights to offer from this on how to avoid the parens, except that zeroth order logic is fundamental and a linguistic approach to programming languages might prove fruitful (grammar, not syntax). And by the by the way: Isn't "everything is an object" similar in power to homoiconicity?
This is the only part of your (very interesting) comment I feel qualified to talk about.
I think there may be something there, but you'd have to be extreme about it, making methods into objects, and proabably even keywords like "if." This is a high bar---but macros clear it.
I would suggest it be an expanded list by default. It would really cut down on dupes and encourage everybody to build on the old conversation instead of rehashing it.
(just kidding
(sardonicly?
(isn't it obvious?
(depends on how one writes it
(like with what editor?
(we all know there is only one editor
(emacs?
(Stallman's own
(not to imply ownership
(as editors should be free
(along with all software
(like knowledge
(which are just ideas with proven value
(requiring recognition
(implying awareness of self
(assumed when using LISP)
)))))))))))))))... I got older and I'm not anymore a dreamer
Legacy code and imperative thinking is heavy.
Now I dabble with Clojure on the side.
Perhaps it's time to start dreaming again?
Rewriting the world for VR/AR is coming up. And unlike the rewrite for mobile, this time our software development environments will be transformed as well (mobile wasn't a place for writing code). And while we're perhaps running out of time for new compiler targets and languages, there seems a lot of potential for changing infrastructure.
For example, a talk went by, which I recall as someone dropping linux instances on google lambda, and setting up deterministic C compilation, for massive parallelism and caching. So push a button, and some seconds later a linux kernel has been recompiled (from empty cache). Which rather changes the constraint space on "our language or type system can't provide nice-thing X, because it would take too long to compile". Golang's story of runs fast on a couple of local cores, may shortly sound like "my IDE runs on a PDP-11!", sort of "that's cute - nice art piece". Is it ok to take two days to run some proof obligation? ... well, is it cached now, so no one ever has to do that again?
Eye tracking; hand/finger tracking; escaping from 2D's crippling real-estate constraints; speech recognition; fine-grain code sharing; rich compilation frameworks ... there's a lot of fun incoming.
You can replace parens with reader macros. You can replace built in names with ordinary macros(in some dialects, even reassign the built-in functions altogether). Don't like the let syntax? Modify it yourself to something completely different.
You could modify Lisp to look like json if you were so inclined.
You have access to the compiler at compile time and runtime. Do whatever you want.
If anything, people should be complaining about other languages that don't allow for syntax modification. Want to not type semicolons in C? You are essentially out of luck, unless you want to make your own preprocessor (I don't think the standard one has enough expressive power to do so, but I'd love to be proved wrong).
Complaining about parentheses takes zero effort though. You don't have to spend a single second trying to understand why it looks weird like that...
But if you care that strongly, you can do something about it.
(I am also kind of hoping that, by the time one gets to reader macros, they will be experienced enough, and will understand why the parentheses exist so that they will no longer care about them)
Good defaults do matter, and I would also echo the feeling that the parentheses get in the way, and that a non-small component of my thinking or polishing process is how to responsibly reduce parentheses. I find that it's generally a modest but palpable boost to visual ease. I do wonder whether there's a better way to denote nested lists?
Over time the advantages of lisp have gotten smaller and smaller, assuming they were ever anything more than the rationalizations of happy users. When the options were Python, Ruby, PHP, C++ 03, and Java, this held much more weight.
If you are working on difficult problems where you actually have to devise non-trivial algorithms, then Lisp is a good choice. The problem then becomes feeding that algorithm – when there are so many great libraries everywhere else to retrieve data from and send to other places, it becomes cumbersome to do it in Lisp.
There is also value in restricting programmer flexibility. I suspect Golang got popular precisely because of its straighjacket (and I say this while staring at Golang code in another monitor).
Turns out most people want Legos. Real artists are fewer in number, but those will want clay instead.
Edit: typo. Edit2: everywhere else
I've spent lots of time crafting the greatest macros and trying to deal with missing/half finished/supported libraries in lots of languages, but at this point I just want to build and spending time on those details isn't worth my time, it doesn't help me make a better product.
It turns out that declaring yourself the greatest and resting on those laurels can lead to myopic overconfidence. There's very little at this time that lisp is actually the best choice for, unless you have very limited reliance on outside libraries, and even then, other languages have different tradeoffs.
Real artists are fewer in number, but those will want clay instead.
This is incredibly pretentious and might not match reality.
I do not see how what I wrote would support this claim
The actual underlying theme was: if you really need a medium to express yourself(or in this case, your thoughts), Lisp is great. The comparison to clay was because: it is mold-able, it is not easy to work with, most people do not want to get their hands dirty with it, they may not even be interested on it. And what most people will make with clay will not look good. This is not a limitation on their part, they may not even be interested.
I am one of those churning out prefabs and gluing stuff together. This is what I get paid for.
I saw the kind of argument that I'm used to hearing lispers make and overreacted. My issue is I'm not really sure that lisp is actually better at doing things at a lower level. You have more freedom with syntax, sure, but I'm not at all convinced that's the same thing as building things up from the bottom. Rust, for example, will let you do low level things that lisp really can't, and Ocaml will let you build up typologies in ways lisp isn't made to.
At the end of the day, languages really aren't that different, especially modern ones, you're mostly working with the same abstractions, and the question becomes is syntactic freedom more important or is a growing community more important? That actually is my biggest issue with lisp (and most other language) evangelism. It's a bunch of claims that aren't really rooted in any kind of evidence.
I had a task to write a code generator from JSON to an internal language, and here lisp really showed its strength. It's just so convenient to first describe your data, then write a function to output a string representation of this data in another language and finally adding small functions and macros to make the DSL look beautiful. Took about three weeks from start to production, and already another developer who was new to lisps jumped in and wrote an extension to the generator.
I could've done this with other languages, especially looking at you OCaml and Haskell, but just grabbing lisp, getting results during the first days and having tremendous amount of fun made the deal.