Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 585
Jeff Pratt Avatar asked Nov 17 '16 17:11

Jeff Pratt


3 Answers

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.

like image 172
Alejandro C. Avatar answered Nov 05 '22 07:11

Alejandro C.


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.

like image 2
Michiel Borkent Avatar answered Nov 05 '22 05:11

Michiel Borkent


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.

like image 2
Leo Avatar answered Nov 05 '22 06:11

Leo