ANDing a boolean and a list - clojure

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.

Related

If nil is treated as a logical false in Clojure, why does (false? nil) return false

The book Living Clojure explains that the type nil is treated the same as logical false.
So I expected (false? nil) to return true, which it doesn't. (true? nil) also doesn't. Both return false, which makes me think that Clojure treats nil neither as true nor false.
On the other hand, (not nil) evaluates to true. So I'm a bit confused.
The distinction is testing for logical truth, versus the values themselves.
The values nil and false are treated as logically false in Clojure. All other values are treated as logically true.
The predicates false? and true? test explicitly for the values false and true respectively, as you have noted. These predicates are not often used in Clojure.
According to the documentation of false?:
Returns true if x is the value false, false otherwise.
So the function checks if the parameter equals the value false instead of checking if it is logically false.
In Clojure, all values are either logically true or logically false, so they can be used in conditional expressions. The only logically false values are nil and false.
There are some good answers already.
People sometimes use the terms falsey (nil and false) and truthy (all other values) to describe Clojure values.
It is sometimes handy to coerce values into Boolean true or false. I even wrote a handy function for this:
(defn truthy?
"Returns true if arg is logical true (neither nil nor false); otherwise returns false."
[arg]
(if arg true false))
(defn falsey?
"Returns true if arg is logical false (either nil or false); otherwise returns false. Equivalent
to (not (truthy? arg))."
[arg]
(if arg false true))
These are sometimes convenient when filtering values or constructing a vector of true/false values.
Later, I discovered Clojure already had a function boolean which does the same thing as truthy?.
Be sure to see this list of documentation sources, especially the Clojure CheatSheet. Enjoy!
The book Living Clojure explains that the type nil is treated
the same as logical false.
First, nil is a value - not a type.
Its type is nameless.
Any reference (object) type can have it as a value.
Second, nil and false are distinct values. You can easily write code that treats them differently:
(map #(case %, nil 1, false 2) [nil false])
=> (1 2)
And nil, for example, puns to an empty sequence,
(count nil)
=> 0
whereas false does not
(count false)
Execution error ...
It is as the first argument to if that nil is equivalent to false.
Paraphrasing the official document:
(if test then else?)
... evaluates test, then ...
if it is nil or false, evaluates and yields else;
otherwise evaluates and yields then.
If else is not supplied, it defaults to nil.
All of the other conditionals (when, if-let, cond,
...) follow the same logic:
nil and false constitute logical falsity;
everything else constitutes logical truth.
As for the predicate function false?, it might have been defined ...
(defn false? [x]
(case x, false true, false))
... which, for any argument but the exact value false, returns false.
By the way, the Clojure values false and true are the Java objects Boolean/FALSE and Boolean/TRUE:
Boolean/FALSE
=> false
(if Boolean/FALSE 1 2)
=> 2
(type false)
=> java.lang.Boolean

Lisp if not nil

I'm trying to do a simple if statement that checks if a variable is nil or not.
(defun test (input)
(let ((testvar (first input)))
(if (not nil testvar)
(do this)
(do that))))
Could anyone explain the proper syntax to me?
Since nil is equivalent to the boolean value false, there is no need to compare to it explicitly.
A simple
(if testvar
(...)
(...))
will do the job. You only need not if you want to check for the opposite, e.g. if you want to check that a variable is not nil:
(if (not testvar)
(...)
(...))
Apart from that, there is also a predicate function called null that you might use. It is basically meant for checking whether a given list is empty, but since the empty list is equivalent to nil, it will work (as the examples on the linked page point out):
(null '()) => T
(null nil) => T
(null t) => NIL
(null 1) => NIL
Anyway, this basically only moves the problem one layer up ;-)
Do you want to check if the variable is nil or if it is not nil?
For not nil: (if v ... ...)
For nil: (if (not v) ... ...)
There are (in CL) many variations which are all logically the same but may indicate intent better: (if (null v) ... ...) if the same as the second case above but might indicate to the reader that you are looking for `()‘ instead of logical falsity (ie an empty list). And there are plenty of other variations.
jkiiski was right:
Just (if (not testvar) ...). Or put the true branch first and do (if testvar ...)

Clojure "and" macro as a symbol

Why do the following statements return different results? And further, how would one write the second statement to receive the expected result of false?
(clojure.core/and false true)
=> false
((resolve 'clojure.core/and) false true)
=> true
The kind folks at #clojure on freenode helped me with an answer.
First, one should try to avoid resolving macros at run-time.
Second, the macro function is implemented as a function that takes in two parameters, besides of the any (&) args. Hence, the correct way to write the second statement above would be
((resolve 'clojure.core/and) nil nil false true) =>
**(clojure.core/let [and__3973__auto__ false] (if and__3973__auto__ (clojure.core/and true) and__3973__auto__))**
Since we are still using a macro, it simply will expand it to code, instead of returning an actual value.
The reason AND is implemented as a macro, is to make short-circuiting possible.
You can see from the REPL:
(defmacro and
"Evaluates exprs one at a time, from left to right. If a form
returns logical false (nil or false), and returns that value and
doesn't evaluate any of the other expressions, otherwise it returns
the value of the last expr. (and) returns true."
{:added "1.0"}
([] true)
([x] x)
([x & next]
`(let [and# ~x]
(if and# (and ~#next) and#))))
Without the macro, an AND function would evaluate all of the predicate given to it without short-circuiting.
In my particular case, this is exactly what I needed; both for AND and OR non short-circuiting functions.
Here follows both functions in case anyone ever needs them:
(defn and* [& xs] (every? identity xs))
(defn or* [& xs] (not= (some true? xs) nil))

confusion with Lisp "if" and 'cons' command

I am reading Land of Lisp by Conrad Barski and I am a bit confused on the use of the 'if' command (to name a few)..
So, I understand that writing if '() means that the list is empty and condition is false and if '(1) means the list is non empty and condition is true.
The question is how does lisp know which expression to choose and output based on the nature (True/False) of the if(1) condition? for example in the code below the statement if '(1) is true but then how and why does lisp choose expression I-AM-TRUE as an output?
(if '(1)
'i-am-true
'i-am-false)
I-AM-TRUE
similarly how and why does it output How-does-this-happen in example below..
(if '(1)
'how-does-this-happen
'any-guesses)
HOW-DOES-THIS-HAPPEN
The structure of an if statement is:
(if condition true-stament false-statement)
In other words, the first statement (true-statement) always happens when condition evals to true, and the second statement (false-statement) happens when the condition evals to false.
if special form is used like this:
(if predicate consequent alternative)
In Common Lisp the false value is the empty list nil, represented by either nil or (). The truth value is T and every other value that is not nil. If the predicate evaluates anything except nil it's true and the consequent gets evaluated. If not the alternative is evaluated.
(defun my-not (x)
(if x nil t))
(my-not ()) ; ==> t
(my-not nil) ; ==> t
(my-not '()) ; ==> t
(my-not 'nil) ; ==> t
(my-not t) ; ==> nil
(my-not 'this-is-atruth-value) ; ==> nil

Clojure koans: (if false []) vs (if false [:a :b :c])

I've started learning Clojure this week. I'm working my way through the conditional koans and don't understand the following assertions:
"Some of them leave you no alternative"
(= [] (if (> 4 3)
[]))
"And in such a situation you may have nothing"
(= nil (if (nil? 0)
[:a :b :c]))
The second one does what I would expect -- the condition evaluates to false-- [EDIT: Actually, it's true and I'm just still not used to 'operator-first' reasoning!], if tries to return the second alternative, finds none, and so returns nil. So, why doesn't the first return nil? Is it because an empty structure is 'close enough' to nil?
Because the first if evaluates to true (as 4 is indeed greater than 3), so else-clause is irrelevant. It returns the then-clause, which is defined and equal to [].