Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

As odd as it may seem, I ended up prefering car/cdr over anything else (except when access to pattern matching and destructuring). I know first/rest, head/tail or even fst/snd are clearer names, but car/cdr ended up as symbols having precisely this meaning in LISP idioms (recursion over cons-cell based lists).

My 1.5cents



As a non-Lisper, I can assure you beyond a shadow of a doubt that having "car" & "cdr" show up in the first few sections of a tutorial is not something that wins people over to Lisp.

I don't mean that I don't understand it. I even know they come from assembler instruction names. And they still look weird to me and still have no meaning despite having read what the abbreviation expands to three or four times.

You'd be far better off shipping "first" & "rest" and whispering to the old hands that you're sure they know how to "fix" the problem in their code, than presenting new people with car & cdr and then try to wedge an explanation into a brain that just threw an exception and went "Wait, what?"


Ah, but how would you easily access the number 6 out of the nested list '((((5 4 3 2 1) 6) 7) 8 9) without one of the cute compositions of "car" and "cdr"? In this case, "cadaar". (Rhetorical question. "car" and "cdr" are neat for their cute composition, but I would never inflict that on someone first learning the language.)


    (def x ((((5 4 3 2 1) 6) 7) 8 9))

    (get-in x (0 0 0 1))
Probably botched quoting, don't know common lisp, only clojure.


For the heck of it, I though I'd try it in scheme with pattern matching...

  (let ((x '((((5 4 3 2 1) 6) 7) 8 9)))
    (syntax->datum
     (syntax-case x ()
       ((((_ p) _) _ ...) #'p))))


One word: lenses.


And how would that look for this particular example?


Definitely not as terse but far more general, flexible and powerful. With car and cdr you're restricted to working on cons cells while lenses are generic.

Some examples (from Haskell):

    >>> ((((5,4,3,2,1),6),7),8,9) & view (_1 . _1 . _2)
    6
    >>> ((((5,4,3,2,1),6),7),8,9) & (_1 . _1 . _2) .~ 4
    ((((5,4,3,2,1),4),7),8,9)
    >>> let foo = ((((5,4,3,2,1),6),7),8,9)
    >>> foo & view (_1 . _1 . _2)
    6
    >>> let six = _1 . _1 . _2
    >>> foo & view six
    6
    >>> foo & six .~ 4
    ((((5,4,3,2,1),4),7),8,9)
    >>> foo & six .~ "abc"
    ((((5,4,3,2,1),"abc"),7),8,9)


Huh.

I like the distinction of car/cdr meaning pointers vs first/rest meaning "start of list/rest of list".

It weirded me out at first, but I came to really appreciate it.


Yep. It's good to have both - the car is the first of a list, and the cdr is the rest, but a cons isn't always a list. Having first and rest exclusively would be short-changing us conceptually.


Indeed. It lets you clearly express in code that those cons cells are actually part of a different structure than a list.


first and rest are already part of the language, no change necessary. You just need to use books that teach using first and rest instead of car and cdr.


I know and agree, but they have some weird syntactic/linguistic quality:

  - both 3 letters each
  - only differ by 1 letter a|d
None of the alternatives have these symmetry, and it (very subjectively) shows in the code.


Its not hard to think of things that meet both of those features that are still better mnemonics for things that are common-language descriptions of what the function yields (e.g., cfc/csc or c1c/c2c for "cons first cell, cons second cell")

car and cdr are mnemonics related to the particular instruction set of the first computer on which Lisp happened to be implemented, which is great for people with a background with system programming on that system, but not so good for anyone else.

They're entrenched enough in the language that they are worth changing unless you are intentionally building a new Lisp-like language from scratch with some other main motivation and the change is just a side issue -- and it is clear that having something that doesn't imply list semantics for cons cells like first/rest does is good -- but car/cdr aren't a particularly good pair.


I know car/cdr history, and didn't like it. Only after trying clojure[1], I had a weird sensation that I was missing car/cdr and that writing in scheme felt better.

If I tried to explain deeper, Lisp focus on recursion over cons-lists was so foreign to the mainstream paradigms, that car/cdr, as most used operations, became symbolic axioms in my mind.

[1] which goes all in on the intuitive, human, pragmatic side of things, throwing away some old lisp idioms.


fst/rst, although having the difference in the middle also seems aesthetically appealing to me.


Neat, but unfortunately the equivalent of CADR (second item in list: first-of-rest) is then FRST, which I think would just be too easy to misinterpret as meaning "first" when reading or writing code in a hurry.


I don't know if cr shortcuts are still used often nowadays (SICP advocates for abstraction layers, accessor functions, CL has destruct-bind, and ml uses pattern matching to dig into data).


Nor do I -- but I'm pretty sure that those shortcuts are pretty much the only good reason for caring much about having names that resemble CAR/CDR in the way FST/RST do. (For any other purpose, I think FIRST/REST are obviously better than FST/RST.)


Good catch.

While writing a toy lisp I looked for other names with structural qualities, actually not names, more symbols since these weren't words.

Things like Oo/oO, xo/ox or _/__.


Yeah, I like car/cdr very much and use them where appropiate because of semantics. Indeed, car/cdr doesn't mean the same as first/rest or head/tail. E.g. head/tail makes sense only if you're talking about lists. But cons-cells can be used to compose different types of data structures.

As funny as it is, people whining about "car/cdr" and saying "language X did it better because it called them first/last, or head/tail" don't realize that it's the language X that lacks semantics to express anything else than lists using cons cells.


@desdiv: If you happen to read this, you appear to have been hellbanned. Not sure why. Just a friendly heads-up.


Thank you so much for letting me know! I've emailed the admins about it.


car/cdr also enables things like caar/cadr, which I personally find much clearer than "headHead" or "headOfHead".




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: