Search code examples
clojureschemecommon-lispelispracket

ANDing a boolean and a list


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?


Solution

  • 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.