← Back to context

Comment by kbp

8 years ago

> car and cdr worked for Lisp because, during the '70s, Lisp as a whole was novel enough to gain a sizable following. It doesn't work today. (And note that, even then, Lisp lost a lot of potential users due to the S-expression based syntax.) I'm firmly in the "first" and "rest" camp

first and rest are bad names for what car and cdr do, in the general case. If you have "Jenny" mapped to "867-5309" in a dictionary, then getting the "Jenny" part of that binding with first and the "867-5309" part with rest doesn't really make any sense. Similarly, if you have a node in a binary search tree, getting the subtree with the lesser elements with first and the subtree with the greater elements with rest also doesn't make any sense.

Lisp, even in the 70s, uses first and rest as synonyms for car and cdr for the case where you are operating on a list. first and rest do not make sense as replacements for car and cdr in the general case, however, and if all you want is to have them as synonyms for when they do make sense, then Lisp has been providing that since the 70s.

If you want precise names to offer as aliases to "first" and "rest", then I think ML-style "head" and "tail" are better names than "car" and "cdr".

  • > If you want precise names to offer as aliases to "first" and "rest", then I think ML-style "head" and "tail" are better names than "car" and "cdr".

    I don't know what you mean by ML-style, as most ML-derived languages call car and cdr fst and snd; I don't know any that call them head and tail.

    But aside from that: really? I think of head and tail as being basically synonymous with first and rest (every language I know of that has built-in head and tail functions, or that idiomatically uses head and tail or abbreviations for variable names, uses them to mean the first element, and the list beyond that element. I don't know any that use them for two parts of a 2-tuple). The left child of a binary tree node being the head and the right side being the tail makes no sense at all to me. Not that car and cdr shouldn't be aliased when they're being used that way, but reading as "element a" and "element b" is better to me than "head" and "tail" which are equally meaningless, but by having English names imply meaning.

    Lisp offers (since the 70s) the aliases first and rest for when conses are being used as lists, and I think those are fine and should be used when you are operating on lists. Conses can be used as other things than lists, though, and first/rest (or head/tail) don't work as meaningful names for any usecase aside from lists. Head/tail are totally equivalent to first/rest to me and I don't really care which pair is used for naming the list-handling functions, but they're both bad sets of names for the cons handling functions.

  • Head and tail make more sense in ML because data gets the stream abstraction. The semantics of car/cdr make sense in the context of Von Neumann memory. It's no accident that car/cdr came from machine code...and that's what Lisp was mostly competing with.

    • I don't see how head and tail make less sense as names for generic elements of a pair than abbreviations derived from idiosyncrasies of a long-dead computer from the 1950s.

      1 reply →

> first and rest do not make sense as replacements for car and cdr in the general case, however, and if all you want is to have them as synonyms for when they do make sense, then Lisp has been providing that since the 70s.

And were it so that one really felt that LISP were incomplete without `first` and `rest`, wouldn't it be trivial to wrap them in custom functions (ie alias them)?

Don't get me wrong, but of all the things that will make learning LISP a bit of work, adding a couple of utility functions isn't on the radar...