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.
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
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
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.
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.
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.
Related
I am trying to check whether a boolean variable (boolVariable) is True (T) using the following code:
(defvar boolVariable T)
(if (= boolVariable T)
(print 'TRUE)
)
However, I get the following error:
=: T is not a number
This seems strange, considering that I thought that you can check whether variables equal booleans in Lisp?
Common Lisp's = compares only numbers and neither t nor boolVariable is number.
There are some other equality predicates like eq, eql, equal or equalp, but in this case, you can just use value of bool-variable (renamed in kebab-case):
(defvar bool-variable t)
(if bool-variable (print 'TRUE))
If with only then-form can be also replaced with when:
(defvar bool-variable t)
(when bool-variable (print 'TRUE))
This question already has an answer here:
Test if array is inside a list in lisp
(1 answer)
Closed 1 year ago.
Common Lisp.
I'm trying to determine if a string is present in a given list.
My goal is to have
(member searched-string my-list)
but I keep getting NIL.
Why does (member "foo" '("foo" "bar")) return NIL?
The default value for the :test keyword parameter is #'eql:
If neither a :test nor a :test-not argument is supplied, it is as if a :test argument of #'eql was supplied.
17.2.1 Rules about Test Functions - Satisfying a Two-Argument Test
Strings are not numbers nor characters, so two strings are eql only if they are eq (identical), but in your example you probably have two different strings allocated. You could have optimizations where string= strings are interned by the compiler, making them eq, but that would be an implementation detail.
Here below, the same foo string is used to build the list, and as an argument to member, and the call actually find the value:
(let ((foo "foo"))
(member foo (list foo "bar")))
=> ("foo" "bar")
But more generally, you want to pass a string comparison function, like string-equal (case-insensitive) or string= (exact case), or simply a general-purpose equality predicate; both examples below find the sarch string:
(member "foo" '("foo" "bar") :test #'equal)
(member "FOO" '("foo" "bar") :test #'equalp)
It's because (eql "foo" "foo") ; ==> nil. While not documented in the CLHS member uses #'eql as the standard test. To get it to use #'equal that also evaluates t for structures that display the same
(equal "foo" "foo") ; ==> t
(member "foo" '("foo" "bar") :test #'equal) ; ==> ("foo" "bar")
A string is stored as an vector of characters and thus unless it is the same object eq and eql will evaluate to nil while equal checks if all the characters in the strings are eql.
NB: (eql "foo" "foo") can also be t. Since it is literals and thus constant data the same code compiled will in some implementation only store "test" once so that they become pointer equal (eq).
I'm having some problem writing a LISP function. The function is defined as
(defun foo (arg1 &optional cont))
(cond ((null arg1) nil)
((= 0 cont) arg1)
((do_something))
((recursive call))))
When i call the function with cont everything works fine, but when I call it just with arg1 the error returned is:
Error: in ZEROP of (NIL) arguments should be of type NUMBER
I guess something is wrong in the condition ((= 0 cont) arg1), can you help me solve this problem?
Thanks
The = function, along with some other ones, expect exclusively numbers.
You need to use EQL or a more general equality comparison (equal, equalp) when you expect NIL to be a valid input; here, NIL is expected because it is the default value of the optional argument.
You could also provide a numerical default value to cont:
... &optional (cont 0) ...
... which might be the correct approach if cont has no reason to be anything else than a number.
In Common Lisp, the special operator quote makes whatever followed by un-evaluated, like
(quote a) -> a
(quote {}) -> {}
But why the form (quote ()) gives me nil? I'm using SBCL 1.2.6 and this is what I got in REPL:
CL-USER> (quote ())
NIL
More about this problem: This is some code from PCL Chapter 24
(defun as-keyword (sym)
(intern (string sym) :keyword))
(defun slot->defclass-slot (spec)
(let ((name (first spec)))
`(,name :initarg ,(as-keyword name) :accessor ,name)))
(defmacro define-binary-class (name slots)
`(defclass ,name ()
,(mapcar #'slot->defclass-slot slots)))
When the macro expand for the following code:
(define-binary-class id3-tag
((major-version)))
is
(DEFCLASS ID3-TAG NIL
((MAJOR-VERSION :INITARG :MAJOR-VERSION :ACCESSOR MAJOR-VERSION)))
which is NIL rather than () after the class name ID3-TAG.
nil and () are two ways to express the same concept (the empty list).
Traditionally, nil is used to emphasize the boolean value "false" rather than the empty list, and () is used the other way around.
The Common LISP HyperSpec says:
() ['nil], n. an alternative notation for writing the symbol nil, used
to emphasize the use of nil as an empty list.
Your observation is due to an object to having more than one representation. In Common Lisp the reader (that reads code and reads expressions) parses text to structure and data. When it's data the writer can print it out again but it won't know exactly how the data was represented when it was initially read in. The writer will print one object exactly one way, following defaults and settings, even though there are several representations for that object.
As you noticed nil, NIL, nIL, NiL, ... ,'nil, 'NIL, (), and '() are all read as the very same object. I'm not sure the standard dictates exactly how it's default representation out should be so I guess some implementations choose one of NIL, nil or maybe even ().
With cons the representation is dependent on the cdr being a cons/nil or not:
'(a . nil) ; ==> (a)
'(a . (b . c)) ; ==> (a b . c)
'(a . (b . nil)) ; ==> (a b)
With numbers the reader can get hints about which base you are using. If no base is used in the text it will use whatever *read-base* is:
(let ((*read-base* 2)) ; read numbers as boolean
(read-from-string "(10 #x10)")) ; ==> (2 16)
#x tells the reader to interpret the rest as a hexadecimal value. Now if your print-base would have been 4 the answer to the above would have been visualized as (2 100).
To sum it up.. A single value in Common Lisp may have several good representations and all of them would yield the very same value. How the value is printed will follow both implementation, settings and even arguments to the functions that produce them. Neither what it accepts as values in or the different ways it can visualize the value tells nothing about how the value actually gets stored internally.
(if '(nil nil)
'print-true
'print-false)
(if '(nil)
'print-true
'print-false)
In the code above, why does the Lisp interpreter always evaluate these forms to true (print-true). I thought nil represented false in Common Lisp.
I am using GNU CLISP.
nil is false. Anything else is true. '(nil) is a list with one element, namely nil. '(nil nil) is a list with two elements, namely nil and nil. Neither of these expressions is the same as nil by itself, so if sees it as true.
nil is equivalent to an empty list.
CL-USER> (if (list ) 'print-true 'print-false)
; prints PRINT-FALSE
CL-USER> (if (list nil) 'print-true 'print-false)
; prints PRINT-TRUE
'(nil) is equiv to (list nil) which is different from an empty list.