Check if not nil in Clojure - clojure

So I'm trying to use a 'some' to implement a recursive function. The way the function works is it returns either 'nil' or a vector of needed information. Then I want the 'some' function to return the first result of a bunch of recursive calls that isn't nil. The problem is that 'true?' returns false for a vector. I can't seem to find a function that distinguishes nil and vectors. Any help?

The question is a bit vague, but you can use the nil? function to test if a value is nil. You can use (complement nil?) as the first arg to some to return the first non-nil value in the coll

identity
https://clojuredocs.org/clojure.core/identity
(identity x)
Returns its argument.

Related

fnil-like function in Clojure for defining output

In Clojure, the fnil function can be used to wrap another function: if the argument of the wrapped function would be nil, the wrapper will change it to something else.
E.g. ((fnil * 0) nil) ; returns 0 However (* nil 0) would throw an NPE.
What I'm asking is if there is a similar, built-in function that modifies the output, in case the input is nil. (In other words, it does not even call the wrapped function, it just returns the default value instead.)
In other words, is there a built-in function equivalent to the following?
(defn ifnil [fun default]
(fn [& args]
(if (some nil? args) default (apply fun args))))
; ((ifnil * nil) 1 2 3) ; returns 6
; ((ifnil * nil) 1 nil 3) ; returns nil
N.B.: As always, "no, there is no such function" is also a valid answer (which I suspect, btw.)
There is no such a function, as far as I know. Your implementation looks well, so why not to use it in your code.
What may be improved here is a better name of the function: ifnil might be a bit confusing for your teammates or those who will support your code.
Also, you said in case the input is nil. But in your code, you check for at least one argument is nil. That differs slightly.
And one more thing, personally I'm not a fan of failing to defaults silently. Maybe, you'd better to validate the input data either manually or using schema/spec and write logs. Because fnil mostly used for non-existing keys with update/update-in. But you function tends to be rather a validator.

clojure cannot apply function via map to list

I seem to have a difficulty understanding how I should use clojure map. I have a list of objects called in-grids where I wan't to use method getCoordinateSystem. I guess it is important that objects in the list are of some Java class. When I directly define function in clojure then map works.
This works:
(.getCoordinateSystem (first in-grids))
but not this
(map .getCoordinateSystem in-grids)
And the error is: java.lang.RuntimeException: Unable to resolve symbol: .getCoordinateSystem in this context
I'm probably missing something really obvious here, but what exactly?
If you have an expression of the form
(map f sequence)
then f should refer to an instance of IFn which is then invoked for every element of sequence.
. is a special form, and .getCoordinateSystem does not refer to an IFn instance.
(.getCoordinateSystem (first in-grids))
is equivalent to
(. (first in-grids) (getCoordinateSystem))
You can construct a function value directly e.g.
(map #(.getCoordinateSystem %) in-grids)
Another choice which is often a handy alternative to map is the for function:
(for [grid in-grids]
(.getCoordinateSystem grid))
Using for in this manner has the same effect as map but is a bit more explicit in the "one-item-at-a-time" nature of the processing. Also, since you are calling the Java function getCoordinateSystem directly you don't need to wrap it inside a Clojure function literal.
As an alternative to Lee's answer, there's the memfn macro, which expands to code similar to that answer.
(map (memfn getCoordinateSystem) in-grids)
(macroexpand '(memfn getCoordinateSystem))
;=> (fn* ([target56622] (. target56622 (getCoordinateSystem))))

Clojure - function or cons?

OK, a fibonacci function in Clojure:
(defn give-fibs []
((fn fib-seq [a b]
(cons a (lazy-seq (fib-seq b (+ a b)))))
0 1))
Now, my question is, when I call it like so, I get an error :
(take 10 give-fibs)
edit, error is - java.lang.IllegalArgumentException: Don't know how to create ISeq from: four_cloj.core$give_fibs
However, it works when I call:
(take 10 (give-fibs))
When I check out what's going on, I can't really explain it:
(class (give-fibs)) ; clojure.lang.Cons
(class give-fibs) ; four_cloj.core$give_fibs
??
give-fibs is just that - the function itself. The concept of a function as a value that can be passed around (for example, as argument to take) takes some getting used to, but it's perfectly sensible and normal.
(give-fibs) is the result of calling give-fibs with no arguments, which is what you want in this context. The result is a list, and each element of a list is a Cons object, which is what class tells you.
In this expression you don't really call give-fibs:
(take 10 give-fibs)
you just pass the function itself to take. What you want is to actually call give-fibs in order to pass result of it to take:
(take 10 (give-fibs))
Remember that the first element in an s-expression is considered to be in function position, that is to say it will be executed. Therefore give-fibs and (give-fibs) are different in that the former is the actual function being passed to take and the latter is calling that function, and therefore returning the result to be passed to take.
Thats why (class give-fibs) is a function, and (class (give-fibs)) is a Cons cell as expected.
Just remember the first var after an opening bracket is in function position and will be executed, and its perfectly valid to pass an unexecuted function to another.

Clojure: Idiomatic way to call contains? on a lazy sequence

Is there an idiomatic way of determining if a LazySeq contains an element? As of Clojure 1.5 calling contains? throws an IllegalArgumentException:
IllegalArgumentException contains? not supported on type: clojure.lang.LazySeq
clojure.lang.RT.contains (RT.java:724)
Before 1.5, as far as I know, it always returned false.
I know that calling contains? on a LazySeq may never return as it can be infinite. But what if I know it isn't and don't care if it is evaluated eagerly?
What I came up with is:
(defn lazy-contains? [col key]
(not (empty? (filter #(= key %) col))))
But it doesn't feel quite right. Is there a better way?
First, lazy seqs are not efficient for checking membership. Consider using a set instead of a lazy seq.
If a set is impractical, your solution isn't bad. A couple of possible improvements:
"Not empty" is a bit awkward. Just using seq is enough to get a nil-or-truthy value that your users can use in an if.You can wrap that in boolean if you want true or false.
Since you only care about the first match, you can use some instead of filter and seq.
A convenient way to write an equality predicate is with a literal set, like #{key}, though if key is nil this will always return nil whether nil is found our not.
All together that gives you:
(defn lazy-contains? [col key]
(some #{key} col))
If you use some instead of filter as in your example, you'll get an immediate return as soon as a value is found instead of forcing evaluation of the entire sequence.
(defn lazy-contains? [coll key]
(boolean (some #(= % key) coll)))
Edit: If you don't coerce the result to a boolean, note that you'll get nil instead of false if the key isn't found.

What is the correct "clojure way" to check if a collection is non empty

I want to write a function that would return the boolean true if the given collection is not empty and false otherwise.
I could either do
defn ..
(boolean (seq coll))
or
defn ..
(not (empty? coll))
As I am new to clojure I was initially inclined to go with #2 (more readable), but the clojure api reference for empty? explicitly says use the idiom (seq coll) instead of (not (empty? coll)), maybe to avoid double negation.
I want to know what is the clojure way to check if a collection is non-empty and return a boolean true/false.
According to Joy of Clojure, nil punning with seq is idiomatic:
(defn print-seq [s]
(when (seq s)
(prn (first s))
(recur (rest s))))
"...the use of seq as a terminating condition is the idiomatic way to test whether a sequence is empty. If we tested [in the above example] just s instead of (seq s), then the terminating condition wouldn't occur even for empty collections..."
The passage from empty?'s docstring which you mentioned means in particular that such a nonempty? function should never be necessary, or even particularly useful, because seq can always stand in for it in Boolean contexts, which in pure Clojure code it can.
If you feel compelled to write such a function nonetheless, I'll say that I like the first approach better. empty? is built on seq anyway, so there's no avoiding calling it; just casting the result to Boolean seems cleaner than two trips through not. For other options, see e.g. nil?, false? (I still prefer the cast).
Incidentally, why do you want to write this...? For calling a Java method with a boolean argument perhaps? In that case, I think the cast would express the intention nicely.
Update: An example to illustrate the latter point:
A simple Java class:
public class Foo {
public static boolean foo(boolean arg) {
return !arg;
}
}
Some Clojure client code:
(Foo/foo nil)
; => NullPointerException
(Foo/foo (boolean nil))
; => true
In addition to Michal Marczyk's excellent answer, I'll point out that there is a specific not-empty function:
http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/not-empty
but it doesn't do exactly what you ask for. (Though it will work in most situations).
Not-empty returns nil if the collection is empty, and the collection itself if the collection is not empty. For predicate tests, that will function well. If you actually need true and false values, then (not (empty? x)) is what you're after.
If you need a boolean, I think (comp not seq) has a nice ring to it.
Example usage:
((comp not seq) coll)
And if you need to store it as a fn for later:
(def not-empty' (comp not seq))