Yeah, lots of this is just swapping out one awkward keyword for another.
If I were doing this I'd also get rid of the * around the hash keyword and either just go with the keyword 'hash' or replace it all together with an operator.
It's almost like lispers want the opposite of java, long verbose keywords and syntax and then as short as possible variable names.
Why not switch the parens to something that's a single keystroke? Why not get rid of the parens in most cases? In some cases this seems to make the parens problem with lisp even worse?
(loop for key being each hash-key of *hash*
using (hash-value val)
when (< (length key) 2)
do (format t "~A~%" val))
> Yeah, lots of this is just swapping out one awkward keyword for another.
Many a well-intentioned Lisper eventually begins to see deficiencies where there are none and attempts to improve their implementation of choice. Common Lisp is one such target because people coming from in-vogue languages are used to the language changing every year or two. Invariably this leads to superficial changes at best which are enabled, surprise of surprises, by Common Lisp because it was designed to be extensible.
My theory is that if your language of choice needs to change its grammar rules to introduce new features you're basically admitting that you should have added macros programmatic access to the reader.
> It's almost like lispers want the opposite of java, long verbose keywords and syntax and then as short as possible variable names.
Well syntax is at a minimum in Common Lisp. It tends to avoid syntactical short-hand. The most common I know of being QUOTE, BACKQUOTE, UNQUOTE, UNQUOTE-SPLICE, and FUNCTION: ' ` , ,@ and #' respectively.
If you read the preface to the first edition of Structure and Interpretation of Computer Programs I think you will find an enlightening explanation of, Why Lisp?. To paraphrase a brief summary: there are very few ways to form compound expressions and hardly any syntax at all so that the programmer can get to the problem at hand within an hour: the language disappears.
The longer names are chosen stylistically based on the maxim that computer programs are meant for humans to read and only incidentally to be executed by a computer.
Lisps are not, contrary to popular mythology, list-processing languages. It's a symbolic language. The relationship between symbol and data allows the programmer to think primarily about the transformations to data without the abstractions becoming weak.
> Why not switch the parens to something that's a single keystroke?
You could. Common Lisp gives you access to the reader. You can write a more fitting syntax you are more comfortable with.
I've written reader macros to parse assembler instructions for an emulator I wrote in Common Lisp.
> this just seems to be moving things around, not really improving anything
That's my impression too. These sorts of experiments are worth trying from time to time in order to see if something can come from them. Maybe something will come out of this.
But ultimately people bike-shed over "car/cdr" and specialized functions for specific data-types (ie: AREF, GET-HASH, etc). You can write higher-order functions to abstract away sequence access and iteration if you want: people have and there are good libraries for it.
The standard hasn't changed AFAIK because:
1. It'd be expensive and nobody wants to fund another ANSI committee.
2. There haven't been any significant proposals the necessitate revisiting the specification.
People complain about the lack of run-time support for concurrency and IO in the specification. I don't think they realize, coming from other languages, that Common Lisp doesn't need it. The specification defines the language and a minimal ball of mud for doing practical work with it. Things like concurrency, threading, and IO are implementation issues and have been solved by high-quality open-source implementations for quite some time. We even have good libraries that provide a cross-platform layer to things like threading.
> People complain about the lack of run-time support for concurrency and IO in the specification. I don't think they realize, coming from other languages, that Common Lisp doesn't need it. The specification defines the language and a minimal ball of mud for doing practical work with it. Things like concurrency, threading, and IO are implementation issues and have been solved by high-quality open-source implementations for quite some time. We even have good libraries that provide a cross-platform layer to things like threading.
In that case, it would be useful to newcomers to introduce those facilities into the core of the language. The more batteries are included, the easier language adoption becomes.
> But ultimately people bike-shed over "car/cdr" and specialized functions for specific data-types (ie: AREF, GET-HASH, etc). You can write higher-order functions to abstract away sequence access and iteration if you want: people have and there are good libraries for it.
To me, this is not bike shedding, but user experience design. The more learning that is required to accomplish a given goal the first time, the less productive and more difficult that goal becomes. "car" and "cdr" are not intuitive to me. Why not use "first" and "rest" or "head" and "tail" for CL21 instead?
> "car" and "cdr" are not intuitive to me. Why not use "first" and "rest" or "head" and "tail" for CL21 instead?
Nothing about programming is intuitive.
The problem here is that you've adopted ideas and notions from another language and are bringing that baggage to Common Lisp. If you learned Common Lisp first you might not have this very issue you describe.
For historical reasons, "car" and "cdr" are the names of special pointers to the elements of a cons cell. There's nothing about them that have anything to do with lists. You just happen to be able to construct lists by linking together cons cells. CAR and CDR simply deference the pointers in the cons cell:
(atom . atom)
Where atom can be a value or a another cons cell. In this visualization it's useful to think of CAR as referring to the "atom on the left" and CDR referring to the "atom on the right." One or both of those atoms could be a cons cell... so there's nothing about CAR or CDR that has anything to do with notions of "first", "last", "head", or "tail."
Those are higher-order functions for operating on linked list and are in the Common Lisp specification anyway.
Suggesting that Common Lisp should remove them is like saying you should remove pointers from C.
> The problem here is that you've adopted ideas and notions from another language and are bringing that baggage to Common Lisp. If you learned Common Lisp first you might not have this very issue you describe.
Indeed, very little about programming is intuitive to a non-programmer. You're also right about me bringing in baggage from other languages. Those are valid points, yet I would still like to see CL become more appealing to programmers from other languages, whose baggage becomes relevant to their intuitions.
> Those are higher-order functions for operating on linked list and are in the Common Lisp specification anyway.
This Common Lisp reference [1] equates "cdr" with "rest". I am not familiar with the source, so is this a good reference? If so, then I must still argue that "rest" returning the cdr of a list instead of all the elements except the first is not intuitive to me. Or maybe I am misunderstanding something. My familiarity is with Clojure, not Common Lisp, so that might be interfering with my ability to understand what you mean here.
> Suggesting that Common Lisp should remove them is like saying you should remove pointers from C.
That is an interesting point. I am not very familiar with the organization of data structures in Common Lisp.
>Those are valid points, yet I would still like to see CL become more appealing to programmers from other languages, whose baggage becomes relevant to their intuitions.
I suspect that's the reason for libraries like CL21.
However the specification for the language known as Common Lisp defines a language that is mutable by the user. We don't need to change the specification to experiment with syntactic changes that could benefit new users.
> This Common Lisp reference [1] equates "cdr" with "rest".
That would be a common mistake I've had to overcome when I first started learning Common Lisp. Consider:
(cdr '(1 . 2))
What's the value?
Hint: It's not a list. So why conflate CDR with REST? They're completely different things.
(cddr '(1 . (2 . 3)))
What's the value? Can you guess how that works? Hint... if it's a macro it might expand to:
Again, not REST. Not a list. It just so happens that when you have a structure like:
(1 2 3 4)
You can get (2 3 4) by:
(cdr '(1 2 3 4))
But that's because:
(1 2 3 4)
Is the same as:
(1 . (2 . (3 . (4 . nil))))
And that is the only syntactical sugar Lisp has afaik. You could configure your printer to print out the actual cons structure if you'd like but the shorthand is useful because this data structure in particular is so eponymous.
> Where atom can be a value or a another cons cell. In this visualization it's useful to think of CAR as referring to the "atom on the left" and CDR referring to the "atom on the right."
Then names like "left" and "right" rather than mnemonics for "contents of address part of register" and "contents of decrement part of register" would make sense.
There's nothing you can call them that will make any more sense than CAR and CDR. You can call them BOB and DOUG, LEFT and RIGHT, UP and DOWN, CAKE and DAFFODIL. It wouldn't matter. They're still just symbols to a function that deferences the associated pointer in a cons cell. The powers that be chose CAR and CDR and they're about as good as any.
The bonus discovery that the (car (cdr some-cons-cell)) could be shortened to CADR via a macro was just icing on the cake. Now we have a macro that can access any part of an abstract tree. Nice.
There's nothing intuitive about programming. There's no analogy you can apply to CAR and CDR or even CONS which will suddenly make sense to your primitive mind. You can't pick up a cons cell in your handle, fiddle with it, and throw it back at the computer. There's no analog in nature which resembles it. It's an ephemeral thing that only exists inside a machine because an idea someone had made it so. So stop looking.
If that's the biggest hurdle to learning Lisp I'd be surprised if someone could be taught to program in any other language. Try teaching C declaration syntax to someone.
char *(*c[10])(int **p);
I can explain a cons cell in five minutes tell you that there are two functions for accessing its sub-parts and we can move on.
Update: I don't mean to say I'd be surprised if someone could be taught to program in any other language in any sort of glib or pejorative sense. Of course one can learn to program without hearing about a cons cell. What I mean by that is it takes some willingness to accept abstract concepts and turn them into symbols in order to learn how to manipulate them.
If that was true, than naming constructs in programming languages wouldn't matter at all.
> If that's the biggest hurdle to learning Lisp
Its not, its just one of many small hurdles that keep Lisp as a fairly niche language, despite its strengths when viewed from a 30,000 foot level.
> Try teaching C declaration syntax to someone.
C-family languages declaration syntax is a major factor in the popularity of dynamically typed languages (newer statically typed languages that are starting to take back some ground mostly reduce both the clutter of that syntax and the need for declarations at all.)
So, other than illustrating the a similar (but larger) problem to the car/cdr problem, I'm not sure what the relevance is.
I think we're diverging off the track here. Naming is important. Programming has borrowed quite a lot from various places to name the often weird, alien "things" we work with. But a rose by any other name is still a rose.
There is no name for which there exists an analog in nature that we can apply to CAR and CDR. You can't think about them intuitively. As demonstrated elsewhere calling them FIRST and REST is a mistake. FIRST, SECOND, THIRD and so one are just English words for for CAR, CADR, CADAR, and so on.
So it's best not to get stuck in the "intuitive" trap. CAR and CDR have stuck around because people have argued about it endlessly for 40 years and haven't come up with a better name. They took on abstract symbols and the people writing Common Lisp code kept shipping systems.
> Its not, its just one of many small hurdles that keep Lisp as a fairly niche language
I don't think that's the reason for it's lack of market share. That has more to do with corporate politics and business. Read up on the history of Symbolics.
tldr; there were once only commercial implementations of Common Lisp that cost far too much and delivered little. Because money.
So a couple generations of programmers didn't get exposed to it as their first language.
> C-family languages declaration syntax is a major factor in the popularity of dynamically typed languages
Is that so? Why then are their interpreters and virtual machines written in C or some other language? PyPy is making an effort but even then... lots of C. Most implementations I've seen of Common Lisp are written in Common Lisp. Odd.
CAR/CDR isn't a problem. I've explained it five times in various posts on this thread. There's even a link to the HyperSpec (the HTML form of the ANSI specification). It's quite simple.
The real problem is that Common Lisp isn't the first language for most "newcomers." So they come packed with notions and biases that they forget to leave at the door. If C is your first language pointers aren't a big deal and you learn to read the declaration syntax. You know it's not great and that it's difficult to pick up but once you get it you move on. In a similar fashion when you pick up Lisp you figure out CAR and CDR.
Changing the names of CAR and CDR isn't going to make Lisp any more appealing to newcomers. You just have to learn what they are and move on.
This is a classic:
http://www.flownet.com/gat/jpl-lisp.html
Also check his open code lisp section!
I would like to add as somebody whose first language was lisp, car/cdr never represented a problem. It looks more balanced than first/rest.
The thing that got me were emacs, SICP lectures and the whole idea of lisp writing lisp. I don't think changing syntax would help much because lisp attracts certain types of people (I believe).
What is complete bullshit? I'm told the Lisp machines were awesome but I've never had the opportunity to use one. I was only starting programming on an Amiga 500 around 89-90 in BASIC. I wouldn't even know what Lisp was until 2007-2008.
Or is my terribly lazy and misinformed history of the AI winter and the rise of inexpensive Unix mainframes inaccurate as to the reason why Lisp suddenly dropped out of vogue? I've only read accounts of it online. If you have a link to a better source I'd be happy to read it. :)
You wrote: '>tldr; there were once only commercial implementations of Common Lisp that cost far too much and delivered little. Because money.
Which is complete bullshit.'
that's bullshit. Complete bullshit.
Lisp Machines were programmed in ZetaLisp (aka Lisp Machine Lisp) and Interlisp. Not Common Lisp. Common Lisp appeared later on Lisp Machines as an additional Lisp dialect and software was than gradually moved to Common Lisp.
The first version of Common Lisp was initially designed between 1982 and 1984. The defining book was published in 1984.
CMUCL, a free Common Lisp, appeared early. CMUCL was many years forked into SBCL, but CMUCL is still available today. KCL, which then was patched into AKCL, ... Which today is ECl, MKCL, GCL! ... appeared early. CLISP, a free implementation in C, appeared early.
A bunch of mid-priced Common Lisps was available for Windows and Macs.
The commercial ones for Unix were Allegro CL, Lucid CL and LispWorks. They were slightly more expensive and great.
There was always a choice of various Common Lisp implementations...
'Unix mainframes?' What is a Unix mainframe? Unix ran on various types of machines, but there was no rise of a Unix mainframes.
Common Lisp was early available with Lisp. Every major university had a site license for a commercial Common Lisp. I used CL on a SUN cluster. Steve Jobs shipped his first NeXT machine with Allegro CL included.
Common Lisp was never bound to Lisp Machines or only on Lisp Machines. Far from it. The whole idea of Common Lisp was to have the language available on a wide variety of machines: personal workstations, PCs, Unix systems, IBM Mainframes and supercomputers like the Cray.
You're right. I don't know where my head was at when I made that comment. I was totally wrong and I apologize the the parent and everyone else who came across it.
Maybe I was struggling to recall Dan Wienreb's post[0] on the failure of Symbolics and somehow confusing that with other things and not making much sense.
If I were doing this I'd also get rid of the * around the hash keyword and either just go with the keyword 'hash' or replace it all together with an operator.
It's almost like lispers want the opposite of java, long verbose keywords and syntax and then as short as possible variable names.
Why not switch the parens to something that's a single keystroke? Why not get rid of the parens in most cases? In some cases this seems to make the parens problem with lisp even worse?
with 5 sets of parens turns into six setsthe former also required fewer shift-character keystroke combinations
while the new syntax ends up with this feels like my hands are wrestling, not typingthis just seems to be moving things around, not really improving anything
I'm not a lisper, so somebody correct me if I'm wrong