Idiomatic `and` & `or` functions (not macros) in Clojure - clojure

Strange as it may sound, I am looking for function versions of the and and or macros in Clojure.
Why? For one I am curious.
Second, I want to use or in precondition and postcondition checks. This does not work:
(defn victor
[x]
{:post (or (nil? %) (vector %))}
;; ...
)
I want the postcondition to check to see if victor returns a vector or nil, but it fails:
#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/or, compiling:(test/test.clj:10:1)>
I don't think bit-and and bit-or are quite what I'm looking for.
Update: This syntax works without an error:
(defn victor
[x]
{:post [(or (nil? %) (vector %))]}
;; ...
)
I'm still curious if functions exist, though.

I think the standard method is simply to wrap and and or in functions, e.g. (fn [x y] (or x y)). In some contexts, another function will work. For example, a note in the clojure docs for and suggests using (every? identity [true false]). some, not-every?, and not-any? can be used in a similar way.

In general, and and or functions would be undesirable because they cannot use short-circuiting. Consider the following code:
(and false some-expensive-fn)
(or true some-expensive-fn)
With and and or as macros the above code won't execute some-expensive-fn, because it is unnecessary to determine the overall truth value of the expression. In function expressions the arguments are evaluated before being passed to the function, but in macros they are not.

#Triangle Man is right. Short-circuiting won't work, but nevertheless you can define your own function versions:
user=> (defn && [x y] (and x y))
#'user/&&
user=> (&& true false)
false
user=> (&& true true)
true
user=> (defn || [x y] (or x y))
#'user/||
user=> (|| true false)
true
user=> (|| true true)
true
user=> (|| false false)
false
user=>

Related

Clojure: pass value if it passes predicate truth test

Is it possible to remove the let statement / avoid the intermediate 'x' in the following code?:
(let [x (f a)]
(when (pred? x) x))
I bumped into this problem in the following use case:
(let [coll (get-collection-somewhere)]
(when (every? some? coll) ; if the collection doesn't contain nil values
(remove true? coll))) ; remove all true values
So if the collection is free of nil values, only not-true values remain, like numbers, strings, or whatever.
So, I'm looking for something like this:
(defn pass-if-true [x pred?]
(when (pred? x) x))
Assuming that you don't want to define that pass-if-true function, the best you can do is an anonymous function:
(#(when (every? some? %)
(remove true? %))
(get-collection-somewhere))
You could also extract the predicate and transformation into parameters:
(#(when (%1 %3) (%2 %3))
(partial every? some?)
(partial remove true?)
(get-collection-somewhere))
The let form is necessary to prevent your collection-building function from running twice:
(f a) or (get-collection-somewhere)
This is a typical idiom and you are doing it correctly.
Of course, you don't need the let if you already have the collection and are not building inside this expression.
However, you may wish to see when-let:
https://clojuredocs.org/clojure.core/when-let
It can save some keystrokes in some circumstances, but this isn't one of them.

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))

Check for NaN in ClojureScript

How can I check if a value is NaN? I'd prefer a solution that can be used in Clojure too without much extra stuff (so I don't want to use an external library, such as underscore). Here is what I tried
(number? js/NaN) ;=> true, well I'd expect false
(= js/NaN (js/parseInt "xx")) ;=> false
(= js/NaN js/NaN) ;=> false, even worse
; This is the best I could come up with
(defn actual-number?
[n]
(or (> 0 n) (<= 0 n)))
You shouldn't compare NaN's - they're always unequal. You should be able to use javascript's built-in isNaN function like
(js/isNaN x)
You can use isNaN js function:
(js/isNaN ..)
Be aware that
(js/isNaN [1,2])
returns true. There are other many cases where js/isNaN does not correspond to what one expects.
If you're using underscore.js in the browser, you can delegate to (.isNaN js/_ ..) instead.
Otherwise, the following function should to the trick:
(defn isNaN [node]
(and (= (.call js/toString node) (str "[object Number]"))
(js/eval (str node " != +" node ))))

Clojure does not have !=?

Does not exist?
Does exist:
Clojure 1.2.0
user=> (not= 1 2)
true
user=> (not= 1 1)
false
user=> (doc not=)
-------------------------
clojure.core/not=
([x] [x y] [x y & more])
Same as (not (= obj1 obj2))
nil
Amusingly, you could define != to be the same as not= if you really wanted:
user=> (def != not=)
#'user/!=
user=> (!= 2 2)
false
user=> (!= 2 3)
true
In a lot of clojure code the ! char means that a function changes the state of something in a way you should watch out for. the clojure transients make heavy use of these
compare-and-set!
alter-meta!
conj!
persistent!
check out http://clojure.github.com/clojure/ and search for the ! character. these functions usually come with caveats like "must be free of side effects"
According to my google search "not=" is the equivalent but I have zero personal familiarity with Clojure.
Is there some reason not= doesn't suit your purposes?

Function composition in Clojure?

Can Clojure implement (g ∘ f) constructions like Haskell's g . f? I'm currently using workarounds like (fn [n] (not (zero? n))), which isn't nearly as nice :)
There is a function to do this in clojure.core called comp. E.g.
((comp not zero?) 5)
; => true
You might also want to consider using -> / ->>, e.g.
(-> 5 zero? not)
; => true
You can use Clojure's reader-macro shortcut for anonymous functions to rewrite your version in fewer keystrokes.
user=> (#(not (zero? %)) 1)
true
For the specific case of composing not and another function, you can use complement.
user=> ((complement zero?) 1)
true
Using not in combination with when and if is common enough that if-not and when-not are core functions.
user=> (if-not (zero? 1) :nonzero :zero)
:nonzero
Another way is (reduce #(%2 %1) n [zero? not]) but I like (comp not zero?), already mentioned by Michal, better.