In Clojure, what is the difference between the true? function and the boolean function?
I see from the source code that a difference does exist (meta-information removed):
(defn boolean [x] (clojure.lang.RT/booleanCast x))
(defn true? [x] (clojure.lang.Util/identical x true))
As you can see from the source code, true? returns true if the value is identical to true. boolean returns true if the value is merely truthy (all values except false and nil).
=> (map true? [true 0 1 :a])
(true false false false)
=> (map boolean [true 0 1 :a])
(true true true true)
Function boolean is a type cast to Clojure's boolean values true or false. It works according to the rules of truthiness as exercised by if and all its progeny: nil and false act false; everything else acts true.
You could define it as
(defn boolean [x]
(case x
(nil false) false
true))
Function true? determines whether the argument is the Clojure value true. You could define it as
(defn true? [x] (identical? true x))
Thus (boolean :whatever) is true, whereas (true? :whatever) is false.
There are some nasties lurking under the surface, due to Java allowing new
Boolean objects to be created. More later.
Related
I am working through some Clojure tutorials and one of the problems is: Implement (boolean x), which works like the built-in boolean function: for nil and false, it returns false, and for all other values it returns true. You can use if in its implementation, but not the build-in boolean.
I cannot figure out how to do this with just the if statement. This works, but is there a better way?
(defn boolean [x]
(cond
(= x nil) false
(= x false) false
:else true))
nil and false are both 'falsey' (i.e. are equivalent to false in a boolean context) so you can do:
(defn boolean [x]
(if x true false))
if expressions are of the form (if condition true-expr false-expr) so if condition evaluates to true the entire expression evaluates to true-expr otherwise false-expr. So if x is truthy (i.e. not nil or false) the expression will evaluate to true. If x is falsey (nil and false are the only falsey values in clojure) then false is returned.
maybe like this?
(defn my-boolean [val]
(not (or (nil? val) (false? val))))
Is Clojure's logical and different from the normal logical and (&&)? Why does this yield true
((and odd? #(> 10 %)) 6)
Doesn't and need 2 true statements to return true?
and doesn't necessarily return true. It actually returns false or nil if any of the given elements is false or nil. If none of them are, then it returns the very last element (it does not return true).
In your case the and returns the function #(> 10 %) (and nothing else) which is then applied to 6 which yields true. This is because both functions are neither nil nor false.
This is how the steps would work:
((and odd? #(> 10 %)) 6)
(#(> 10 %) 6)
;; => true
What you're looking for is to compose predicate functions:
((every-pred odd? #(> 10 %)) 6) ;; => false
FYI: There is also it's complement "or": some-fn.
Why the following returns false? I expect it should return true since one element of the vector is really false
user=> (contains? [1 false] false)
false
contains? checks for the presence of a key in an associative collection. false is a value, not a key, in [1 false]. Only 0 and 1 are keys. You should use:
(some false? [1 false])
I am trying co join two list using map and logical function "and"
(map and '(true false true) '(0 1 2))
I expect to see
(0 false 2)
Instead of that
CompilerException java.lang.RuntimeException: Can't take value of a macro:
#'clojure.core/and, compiling:(NO_SOURCE_PATH:274:1)
occures.
How can I fix it?
You can wrap the "and" macro into a function
(map #(and % %2) '(true false true) '(0 1 2))
Result:(0 false 2)
The map function don't let you to use macros as first argument, so this is an easy trick to solve the problem
accepted answer is definitely solid, I just wanted to give you an example of converting a macro to a function (mostly for entertaining/learning purposes):
(defmacro to-fun [macro] ;; converting a macro to a function
`#(eval (cons '~macro %&))) ;; e.g. "eval"uated at run time vs. compile time,
;; and hence can be composed
now we can just wrap a(ny) macro with it:
(map (to-fun and) [true false true] [0 1 2])
(0 false 2)
or:
(map (to-fun or) [true false true] [0 1 2])
(true 1 true)
What is fundamental difference for having a '?' in every? and not in some functions of clojure?
user> (every? true? [true true false])
false
user> (some true? [true false false])
true
Thanks.
every? returns true or false, so it gets a question mark. some doesn't return a boolean, it returns "the first logically true value returned by pred", and returns nil otherwise.
Here's the lame example I came up with:
user=> (some #(if (= 0 %) 1 0) [1 3 5 0 9])
0
The first element in the collection gets passed into the predicate, the predicate evaluates to 0, which is logically true so some returns 0. you can see some is not returning true or false.
So every? gets a question mark because it returns true or false.
some returns the value returned by pred or nil, so it doesn't get a question mark.
some doesn't necessarily return a Boolean, whereas every? always does. See the documentation.
Returns the first logical true value of (pred x) for any x in coll,
else nil. One common idiom is to use a set as pred, for example
this will return :fred if :fred is in the sequence, otherwise nil:
(some #{:fred} coll)