What is the exact difference between NULL and NIL in Common Lisp?
Asked Answered
A

5

6

As far as I understood, NIL is a symbol for many things: empty lists, or the boolean false. So far so good, but why there is sometimes NULL showing up in the output?

clisp> (type-of NIL)
NULL
clisp> (type-of t)
BOOLEAN
clisp> (type-of (not t))
NULL
clisp> NIL
NIL
clisp> (eq NULL NIL)
ERROR..

So NULL is not a defined symbol as "BASIC-STRING-6" is not one either. But I am a little confused by the term NULL as a boolean should stay a boolean nonetheless if it is negated or not.

Alyss answered 23/5, 2014 at 9:55 Comment(1)
Try (type-of "elephant") and (type-of (not "elephant")). The fact that t happens to be a boolean is accidental.Leonteen
S
5

You might think it's strange that T is a boolean while NIL isn't. The reason is that NIL has several hats. It's the empty list, it's the symbol NIL, it's boolean false. So it sometimes occurs in contexts not appropriate for a boolean-typed value, hence the type boolean is not appropriate for it from a type-safety perspective. Somewhat similarly, in Scheme boolean false is different from the empty list.

NULL is given as the type of NIL.

NIL is the symbol that represents NULL in Common Lisp. It is also the representation of the empty list (). #'NULL is the function that checks if a variable is NULL (ie. eq NIL).

You may define NULL if you want to use NULL instead of NIL. (This is probably a terrible idea in practice.)

(defconstant null nil)
(type-of NULL) ; ==> NULL
NULL           ; ==> NIL
(eq NULL NIL)  ; ==> T
Stiegler answered 23/5, 2014 at 10:52 Comment(5)
What most helped me in understanding, that NIL is actually just a symbol, but a very special one.Alyss
While it's possible to define null, it's probably not a good idea because it would lead unidiomatic code that would catch people off guard.Ghibelline
"You might think it's strange that T is a boolean while NIL isn't." Except that nil is a boolean, as (typep nil 'boolean) => T confirms.Ghibelline
@JoshuaTaylor Every object in CL is a boolean. When I wrote this I write what the OP experienced with his use of type-of. Thus most specific type. Also notice @osa has edited this after I wrote it over a year ago.Stiegler
Yes and no... I understand what you mean, but for the sake of less experienced readers who find this question, the type boolean contains just the symbols t and nil. But everything is a generalized boolean, and most operators accept generalized booleans.Ghibelline
G
9

NIL is a symbol. It's also written as (). The output of type-of is not necessarily useful here. the HyperSpec says about type-of:

Returns a type specifier, typespec, for a type that has the object as an element.

But given type hierarchies, as well as a universal type (everything is of type t), the output of type-of can be unhelpful. What's more useful here, if you want to know whether something has a particular type is typep. Using typep, we can see that, regardless of what type-of tells us, that nil is a boolean, is a symbol, and is a list, and a null. On the other hand, t is a symbol, a boolean, not a list, and not a null.

CL-USER> (type-of nil)
NULL
CL-USER> (type-of t)
BOOLEAN
CL-USER> (typep nil 'boolean)   ; both are booleans
T
CL-USER> (typep t 'boolean)
T
CL-USER> (typep nil 'symbol)    ; both are symbols
T
CL-USER> (typep t 'symbol)
T
CL-USER> (typep nil 'list)      ; only nil is a list
T
CL-USER> (typep t 'list)
NIL
CL-USER> (typep nil 'null)      ; only nil is a null
T
CL-USER> (typep t 'null)
NIL
Ghibelline answered 23/5, 2014 at 13:59 Comment(0)
S
5

You might think it's strange that T is a boolean while NIL isn't. The reason is that NIL has several hats. It's the empty list, it's the symbol NIL, it's boolean false. So it sometimes occurs in contexts not appropriate for a boolean-typed value, hence the type boolean is not appropriate for it from a type-safety perspective. Somewhat similarly, in Scheme boolean false is different from the empty list.

NULL is given as the type of NIL.

NIL is the symbol that represents NULL in Common Lisp. It is also the representation of the empty list (). #'NULL is the function that checks if a variable is NULL (ie. eq NIL).

You may define NULL if you want to use NULL instead of NIL. (This is probably a terrible idea in practice.)

(defconstant null nil)
(type-of NULL) ; ==> NULL
NULL           ; ==> NIL
(eq NULL NIL)  ; ==> T
Stiegler answered 23/5, 2014 at 10:52 Comment(5)
What most helped me in understanding, that NIL is actually just a symbol, but a very special one.Alyss
While it's possible to define null, it's probably not a good idea because it would lead unidiomatic code that would catch people off guard.Ghibelline
"You might think it's strange that T is a boolean while NIL isn't." Except that nil is a boolean, as (typep nil 'boolean) => T confirms.Ghibelline
@JoshuaTaylor Every object in CL is a boolean. When I wrote this I write what the OP experienced with his use of type-of. Thus most specific type. Also notice @osa has edited this after I wrote it over a year ago.Stiegler
Yes and no... I understand what you mean, but for the sake of less experienced readers who find this question, the type boolean contains just the symbols t and nil. But everything is a generalized boolean, and most operators accept generalized booleans.Ghibelline
L
3

The exact difference is that NULL is a type in your context, while NIL is a symbol.

NULL is the type containing only the symbol NIL.

NIL as a type is the empty type (there is no object that has type NIL):

NIL as an object is the symbol representing various "not"-things.

Lamrouex answered 23/5, 2014 at 12:24 Comment(0)
C
1

So NULL is not a defined symbol as "BASIC-STRING-6" is not one either.

NULL is a symbol. It has no value. The symbol NULL is the name of a type NULL and the function NULL. NULL as a type has one element: NIL.

NIL is a symbol and NIL is its value. Thus NIL is a constant with itself as the value. NIL is also a type, the empty type with no object.

Condemn answered 27/5, 2014 at 21:57 Comment(0)
K
-1

Types designators like INTEGER, (ARRAY *), (MEMBER T NIL), etc. do not evaluate to a value. So it is unsurprising that the type name NULL raises an error if you attempt to evaluate it. Recall that the type/subtype hierarchy is not a simple tree, so NULL is a subtype of many things; CONS, BOOLEAN, LIST, etc.

Beware that many things are treated as true that aren't of type BOOLEAN. BOOLEAN is just short hand for '(member nil t). so (type 'foo '(member nil t)) is equvalent to '(typep 'foo 'boolean).

At about this point in the learning curve is is worth remembering the Common Lisp is dynamically typed and the the type declarations trend more toward documentation and advise which the compiler's optimizer and warning subsystems can take or ignore.

NULL is also a function. Checking the manual's index might have helped you.

Kapp answered 25/5, 2014 at 13:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.