I've noticed in Scheme, Racket, and Clojure that the expression (using Clojure here) (and true '())
evaluates to ()
, and (and '() true)
evaluates to true
. This is true not only for the empty list, but for any list.
But in GNU CLISP and Emacs Lisp, (and t '())
evaluates to nil
and (and '() t)
evaluates to nil
also, but (and t '(1 2 3))
evaluates to (1 2 3)
and (and '(1 2 3) t)
evaluates to t
.
What is going on here?
In the first group of languages, the empty list is not treated as 'falsey' and is instead treated as a 'truthy' value. In scheme and racket, #false
is the only false value so even though '()
is null, null is not false; in clojure the empty list is not the same as nil, so it is 'truthy' there as well.
In the second group, the empty list is a synonym for nil
and is treated as false, leading the condition to return nil
. A list with elements however is not the same as nil, and thus is treated as a truthy value again.
The final piece of the puzzle is that and
returns the last truthy value if all values passed are truthy.
In Clojure only false
and nil
are regarded as logically false. Everything else is regarded as logically true.
In the other Lisps you mention, the empty list is regarded as logically false.
The and
operator evaluates the arguments and 'shortcircuits' the result, i.e. as soon as one argument is false, it returns nil. Otherwise, it returns the last value.
The difference in behavior is that in Common Lisp, the empty list is the same thing as nil
, which is the same as false, therefore, (and '() t)
is the same as (and nil t)
which returns nil
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With