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

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 [].

Related

Clojure loop collection

I want to know if this is the right way to loop through an collection:
(def citrus-list ["lemon" "orange" "grapefruit"])
(defn display-citrus [citruses]
(loop [[citrus & citruses] citruses]
(println citrus)
(if citrus (recur citruses))
))
(display-citrus citrus-list)
I have three questions:
the final print displays nil, is it ok or how can avoid it?
I understand what & is doing in this example but I donĀ“t see it in other cases, maybe you could provide a few examples
Any other example to get the same result?
Thanks,
R.
First of all your implementation is wrong. It would fail if your list contains nil:
user> (display-citrus [nil "asd" "fgh"])
;;=> nil
nil
And print unneeded nil if the list is empty:
user> (display-citrus [])
;;=> nil
nil
you can fix it this way:
(defn display-citrus [citruses]
(when (seq citruses)
(loop [[citrus & citruses] citruses]
(println citrus)
(if (seq citruses) (recur citruses)))))
1) it is totally ok: for non-empty collection the last call inside function is println, which returns nil, and for empty collection you don't call anything, meaning nil would be returned (clojure function always returns a value). To avoid nil in your case you should explicitly return some value (like this for example):
(defn display-citrus [citruses]
(when (seq citruses)
(loop [[citrus & citruses] citruses]
(println citrus)
(if (seq citruses) (recur citruses))))
citruses)
user> (display-citrus citrus-list)
;;=> lemon
;;=> orange
;;=> grapefruit
["lemon" "orange" "grapefruit"]
2) some articles about destructuring should help you
3) yes, there are some ways to do this. The simplest would be:
(run! println citrus-list)
Answering your last question, you should avoid using loop in Clojure. This form is rather for experienced users that really know what they do. In your case, you may use such more user-friendly forms as doseq. For example:
(doseq [item collection]
(println item))
You may also use map but keep in mind that it returns a new list (of nils if your case) that not sometimes desirable. Say, you are interested only in printing but not in the result.
In addition, map is lazy and won't be evaluated until it has been printed or evaluated with doall.
For most purpose, you can use either map, for or loop.
=> (map count citrus-list)
(5 6 10)
=> (for [c citrus-list] (count c))
(5 6 10)
=> (loop [[c & citrus] citrus-list
counts []]
(if-not c counts
(recur citrus (conj counts (count c)))))
[5 6 10]
I tend to use map as much of possible. The syntax is more concise, and it clearly separates the control flow (sequential loop) from the transformation logic (count the values).
For instance, you can run the same operation (count) in parallel by simply replacing map by pmap
=> (pmap count citrus-list)
[5 6 10]
In Clojure, most operations on collection are lazy. They will not take effect as long as your program doesn't need the new values. To apply the effect immediately, you can enclose your loop operation inside doall
=> (doall (map count citrus-list))
(5 6 10)
You can also use doseq if you don't care about return values. For instance, you can use doseq with println since the function will always return nil
=> (doseq [c citrus-list] (println c))
lemon
orange
grapefruit

Idiomatic and lazy eventually truthy in a list in Clojure

I'd like to have a function/macro for checking a list to have truthy value eventually, and I hope the evaluation would be lazy. Here is my illustrative implementation without lazy evaluation:
(defn eventual [cols]
(or (first cols) (if-let [rs (rest cols)]
(eventual rs))
false))
Here is a trivial example to illustrate:
(if (eventual [false (+ 1 2) (* 10000 10000)])
true
false)
I feel that there must be an implication with lazy evaluation. Maybe I'm just blinded at the moment. Please help to help. Thanks
You can check if a sequence contains at least one truthy element with some function:
(some identity col)
If you pass it a lazy sequence as col it will evaluate its contents up to the first truthy element and won't realise the rest:
(let [col (take
10
(iterate
#(do (println "Generating new value from " %) (inc %))
0))]
(some #(> % 5) col))
produces:
Generating new value from 0
Generating new value from 1
Generating new value from 2
Generating new value from 3
Generating new value from 4
Generating new value from 5
true
As you can see, values 6..9 are not produces at all.
You also should double check that the col you pass to some is really lazy and not already realised, because it might confuse you.
Your eventual function is as lazy as it can be. It searches eagerly for the first truthy item then stops. But it has problems:
It fails to terminate on an empty collection. (rest ()) is (),
which is truthy. Use next instead of rest. (next ()) is nil,
which is falsy.
It is truly recursive. It will blow the stack on a long enough
search. Try (eventual (repeat false)). Since the recursion is
tail-recursion, you can fix this by using recur in its place.
While we are at it, it is idiomatic to return nil, not false,
upon running out of a collection. So drop the final false.
We end up with
(defn eventual [cols]
(or (first cols) (if-let [rs (next cols)]
(recur rs))))
I'm a little queasy about what happens if cols is empty. Code based upon the source for some is clearer:
(defn eventual [coll]
(when (seq coll)
(or (first coll) (recur next coll))))
But using (some identity col), as Piotrek suggests, is probably best.

In clojure, what is the exact behaviour of identical?

I am very surprised by the behaviour of identical? in clojure.
(def a (map identity [:a :b]))
(identical? (rest a) (rest a)); false
Any idea why identical? returns false?
identical?:
Tests if 2 arguments are the same object
Since rest creates a new seq object on each invocation, its results are not identical?. The following, however, is:
(def r (rest (map identity [:a :b])))
(identical? r r) ;; => true
Update: As #mfikes pointed out, rest does not always create a new seq. It calls ISeq.more() internally which is implemented per seq type and might yield different results for lists, vectors, lazy seqs, etc.:
(->> [(map identity [:a :b])
(vector :a :b)
(list :a :b)]
(map #(identical? (rest %) (rest %))))
;; => [false false true]
identical? is the object equality predicate. It returns true if its arguments are the same object/primitive.
Use = over identical?.
identical? is the correct tool when semantics depend on pointer equality, such as testing for an end-of-file sentinel value.
Never use identical? to compare Clojure data structures. Even keywords don't guarantee identical? behaves correctly.

Equivalent of every-pred, but for any of the given predicates

Any cuter way to express this?
#(or (:a %) (b: %) (:c %)) ;; would prefer (desired-fn :a :b :c)
clojure.core lacks a "any-pred" function, maybe because there is already a means of providing the same functionality? Or would have one to implement it himself?
some-fn is what you're looking for. The only difference is that some-fn will return false rather than nil in the case where none of the functions return a logically true value.
Just as a note on naming: it's not called "some-pred"/"any-pred" because predicates only return true or false, whereas some-fn will return the first logically true value (which may not be true itself).

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