←back to thread

Hofstadter on Lisp (1983)

(gist.github.com)
372 points Eric_WVGG | 1 comments | | HN request time: 0s | source
Show context
susam ◴[] No.41861244[source]
> Attempting to take the car or cdr of nil causes (or should cause) the Lisp genie to cough out an error message, just as attempting to divide by zero should evoke an error message.

Interestingly, this is no longer the case. Modern Lisps now evaluate (car nil) and (cdr nil) to nil. In the original Lisp defined by John McCarthy, indeed CAR and CDR were undefined for NIL. Quoting from <https://dl.acm.org/doi/pdf/10.1145/367177.367199>:

> Here NIL is an atomic symbol used to terminate lists.

> car [x] is defined if and only if x is not atomic.

> cdr [x] is also defined when x is not atomic.

However, both Common Lisp and Emacs Lisp define (car nil) and (cdr nil) to be nil. Quoting from <https://www.lispworks.com/documentation/HyperSpec/Body/f_car...>:

> If x is a cons, car returns the car of that cons. If x is nil, car returns nil.

> If x is a cons, cdr returns the cdr of that cons. If x is nil, cdr returns nil.

Also, quoting from <https://www.gnu.org/software/emacs/manual/html_node/elisp/Li...>:

> Function: car cons-cell ... As a special case, if cons-cell is nil, this function returns nil. Therefore, any list is a valid argument. An error is signaled if the argument is not a cons cell or nil.

> Function: cdr cons-cell ... As a special case, if cons-cell is nil, this function returns nil; therefore, any list is a valid argument. An error is signaled if the argument is not a cons cell or nil.

replies(6): >>41861327 #>>41861751 #>>41862379 #>>41862873 #>>41862933 #>>41868929 #
lisper ◴[] No.41862873[source]
> Modern Lisps now evaluate (car nil) and (cdr nil) to nil.

Scheme doesn't. Taking the CAR or CDR of nil is an error.

replies(3): >>41863007 #>>41863233 #>>41868861 #
pmarreck ◴[] No.41868861[source]
I'm not a LISPer but this just seems more correct to me, since stricter is usually more correct.

Ruby (not a lisp but bear with me) started to do this more correctly IMHO where a nil would start throwing errors if you tried to do things with it BUT it would still be equivalent to false in boolean checks.

replies(1): >>41870516 #
lisper ◴[] No.41870516[source]
It depends on what you are trying to optimize for. There is a benefit to punning the empty list and boolean false. It lets you shorten (not (null x)) to just x, and that is a common enough idiom that it actually makes a difference in real code. And there is a benefit to being able to say or type "nil" instead of "the empty list" because "nil" is shorter. But yeah, for modern production code, I agree that stricter is better, all else being equal.
replies(2): >>41880552 #>>41880728 #
pmarreck ◴[] No.41880552[source]
I love that I started out saying "I'm not a LISPer" and someone whose username is literally "lisper" responded. >..<

Is there a purely functional Lisp that compiles to machine code yet?

replies(1): >>41880724 #
lisper ◴[] No.41880724[source]
That depends on what you mean by "purely functional Lisp". You can write purely functional code in any Lisp, and you can compile any Lisp to machine language, and this has been true for decades. AFAIK there is no Lisp that enforces purely functional programming, but it's easy to build one if that's what you want.
replies(1): >>41895770 #
1. pmarreck ◴[] No.41895770[source]
That is what I want.

Turns out that LFE (Lisp-Flavored Erlang) exists…

Wait, doesn’t Clojure have this, to a large degree at least?