How do I get a default value from first in Clojure? - clojure

(> 1 (first [])) returns NullPointerException.
How can I make (first []) return a default value, such as 0, instead of nil?

You can use or to bypass the nil value
(> 1 (or (first []) 0))
Because in Clojure, nil is treated as a falsy value.

The or solution is good for this case. For cases where or is not sufficient, another option is to use the with-exception-default macro from the Tupelo library:
(with-exception-default default-val & body)
"Evaluates body & returns its result. In the event of an exception the
specified default value is returned instead of the exception."
(with-exception-default 0
(Long/parseLong "12xy3"))
;=> 0

Use fnil:
A function that replaces a nil second argument to > with 0 is ...
(fnil > nil 0)
So that, for instance,
((fnil > nil 0) 1 (first []))
=> true

imho you should clearly define the functional objects in your design
since you need a functionality: given a collection coll extract the first element or default to 0 then you should have a separate function for that.
e.g.
(defn first-or-zero [coll]
(if (seq coll)
(first coll) 0))
Although a bit cumbersome to write (and the or macro does seem to get you there quicker you are missing out on the powerful concept that is FP.
a) doing this way you have a pure functional description of what you need to do
b) you can test it either by proof or by unit-testing
c) you can reuse it all over the place with minimum impact on change
A more FP way of doing it would be:
(defn first-or-default
([coll] (first-or-default coll 0))
([coll dflt-val]
(if (seq coll)
(first coll) dflt-val)))
Then just call: (< 1 (first-or-default coll 0))

Related

creating a finite lazy sequence

I'm using the function iterate to create a lazy sequence. The sequence keeps producing new values on each item. At one point however the produced values "doesn't make sense" anymore, so they are useless. This should be the end of the lazy sequence. This is the intended behavior in a abstract form.
My approach was to let the sequence produce the values. And once detected that they are not useful anymore, the sequence would only emit nil values. Then, the sequence would be wrapped with a take-while, to make it finite.
simplified:
(take-while (comp not nil?)
(iterate #(let [v (myfunction1 %)]
(if (mypred? (myfunction2 v)) v nil)) start-value))
This works, but two questions arise here:
Is it generally a good idea to model a finite lazy sequence with a nil as a "stopper", or are there better ways?
The second question would be related to the way I implemented the mechanism above, especially inside the iterate.
The problem is: I need one function to get a value, then a predicate to test if it's valid, if yes: in needs to pass a second function, otherwise: return nil.
I'm looking for a less imperative way tho achieve this, more concretely omitting the let statement. Rather something like this:
(defn pass-if-true [pred v f]
(when (pred? v) (f v)))
#(pass-if-true mypred? (myfunction1 %) myfunction2)
For now, I'll go with this:
(comp #(when (mypred? %) (myfunction2 %)) myfunction1)
Is it generally a good idea to model a finite lazy sequence with a nil as a "stopper", or are there better ways?
nil is the idiomatic way to end a finite lazy sequence.
Regarding the second question, try writing it this way:
(def predicate (partial > 10))
(take-while predicate (iterate inc 0))
;; => (0 1 2 3 4 5 6 7 8 9)
Here inc takes the previous value and produces a next value, predicate tests whether or not a value is good. The first time predicate returns false, sequence is terminated.
Using a return value of nil can make a lazy sequence terminate.
For example, this code calculates the greatest common divisor of two integers:
(defn remainder-sequence [n d]
(let [[q r] ((juxt quot rem) n d)]
(if (= r 0) nil
(lazy-seq (cons r (remainder-sequence d r))))))
(defn gcd [n d]
(cond (< (Math/abs n) (Math/abs d)) (gcd d n)
(= 0 (rem n d)) d
:default (last (remainder-sequence n d))))
(gcd 100 32) ; returns 4

Thread through functions unless not null

Is there a built in macro for that?
(defn keep-looking-for-value-in-multiple-sources [value source1 source2 ...]
(let [ ret (source1 value)]
(if ret
ret
(let [ret (source2 value)]
(if ret
ret
(...))))
)
)
I know it's easy to implement a macro, but maybe there is a idiomatic approach?
Depending on whether you can live with false being treated equally to nil (as your example suggests), you could just use or:
(or (source1 value)
(source2 value)
...)
This should not be unreasonably verbose in most cases, but obviously only works if you know (and explicitly use) the collection of functions you want to apply.
This is what I've come up with
(some #(% value) [source1 source2])
You don't need a macro. The function you specify is roughly as you have it, with a suitable frame:
(defn keep-looking-for-value-in-multiple-sources [value & sources]
(some #(% value) sources))
But is this really what you want? For example,
(keep-looking-for-value-in-multiple-sources -2 pos? odd? even?)
;true
... not very informative.
I blame some. For example, if I write
(some odd? (range))
... I intuitively expect 1. In fact, I get true, the first truthy result of applying odd? to successive elements of (range). There is no standard function that does what, IMO, some ought to do.
user> (defn keep-looking [value & sources]
(loop [s sources]
(if-let [ret ((first s) value)]
ret
(recur (rest sources)))))
#'user/keep-looking
user> (keep-looking :something
{:not-something 1}
{:something 3})
;=> 3

Return the first non empty/blank value?

I have 2 bindings I'm calling path and callback.
What I am trying to do is to return the first non-empty one. In javascript it would look like this:
var final = path || callback || "";
How do I do this in clojure?
I was looking at the "some" function but I can't figure out how to combine the compjure.string/blank check in it. I currently have this as a test, which doesn't work. In this case, it should return nil I think.
(some (clojure.string/blank?) ["1" "2" "3"])
In this case, it should return 2
(some (clojure.string/blank?) ["" "2" "3"])
(first (filter (complement clojure.string/blank?) ["" "a" "b"]))
Edit: As pointed out in the comments, (filter (complement p) ...) can be rewritten as (remove p ...):
(first (remove clojure.string/blank? ["" "a" "b"]))
If you are so lucky to have "empty values" represented by nil and/or false you could use:
(or nil false "2" "3")
Which would return "2".
An equivalent to your JavaScript example would be:
(let [final (or path callback "")]
(println final))
If you want the first non blank string of a sequence you can use something like this:
(first (filter #(not (clojure.string/blank? %)) ["" "2" "3"]))
This will return 2
What i don't understand is your first example using the some function, you said that it should return nil but the first non blank string is "1".
This is how you would use the some function:
(some #(when-not (empty? %) %) ["" "foo" ""])
"foo"
(some #(when-not (empty? %) %) ["bar" "foo" ""])
"bar"
As others have pointed out, filter is another option:
(first (filter #(not (empty? %)) ["" "" "foo"])
"foo"
A third option would be to use recursion:
(defn first-non-empty [& x]
(let [[y & z] x]
(if (not (empty? y))
y
(when z (recur z)))))
(first-non-empty "" "bar" "")
"bar"
(first-non-empty "" "" "foo")
"foo"
(first-non-empty "" "" "")
nil
I used empty? instead of blank? to save on typing, but the only difference should be how whitespace is handled.
It was difficult for me to tell exactly what you wanted, so this is my understanding of what you are trying to do.
In my case, I wanted to find if an item in one report was missing in a second report. A match returned nil, and a non-match returned the actual item that did not match.
The following functions wind up comparing the value of a mapped value with a key.
Using something like find-first is probably what you want to do.
(defn find-first
"This is a helper function that uses filter, a comparision value, and
stops comparing once the first match is found. The actual match
is returned, and nil is returned if comparision value is not matched."
[pred col]
(first (filter pred col)))
(defn str-cmp
"Takes two strings and compares them. Returns 0 if a match; and nil if not."
[str-1 str-2 cmp-start-pos substr-len]
(let [computed-str-len (ret-lowest-str-len str-1 str-2 substr-len)
rc-1 (subs str-1 cmp-start-pos computed-str-len)
rc-2 (subs str-2 cmp-start-pos computed-str-len)]
(if (= 0 (compare rc-1 rc-2))
0
nil)))
(defn cmp-one-val
"Return nil if first key match found,
else the original comparision row is returned.
cmp-row is a single sequence of data from a map. i
cmp-key is the key to extract the comparision value.
cmp-seq-vals contain a sequence derived from
one key in a sequence of maps.
cmp-start and substr-len are start and stop
comparision indicies for str-cmp."
[cmp-row cmp-key cmp-seq-vals cmp-start substr-len]
(if (find-first #(str-cmp (cmp-key cmp-row) %1 cmp-start substr-len) cmp-seq-vals)
nil
cmp-row))

Clojure Partial Application - How to get 'map' to return a collection of functions?

I have a function that I basically yanked from a discussion in the Clojure google group, that takes a collection and a list of functions of arbitrary length, and filters it to return a new collection containing all elements of the original list for which at least one of the functions evaluates to true:
(defn multi-any-filter [coll & funcs]
(filter #(some true? ((apply juxt funcs) %)) coll))
I'm playing around with making a generalizable solution to Project Euler Problem 1, so I'm using it like this:
(def f3 (fn [x] (= 0 (mod x 3))))
(def f5 (fn [x] (= 0 (mod x 5))))
(reduce + (multi-any-filter (range 1 1000) f3 f5))
Which gives the correct answer.
However, I want to modify it so I can pass ints to it instead of functions, like
(reduce + (multi-any-filter (range 1 1000) 3 5))
where I can replace 3 and 5 with an arbitrary number of ints and do the function wrapping of (=0 (mod x y)) as an anonymous function inside the multi-any-filter function.
Unfortunately this is past the limit of my Clojure ability. I'm thinking that I would need to do something with map to the list of args, but I'm not sure how to get map to return a list of functions, each of which is waiting for another argument. Clojure doesn't seem to support currying the way I learned how to do it in other functional languages. Perhaps I need to use partial in the right spot, but I'm not quite sure how.
In other words, I want to be able to pass an arbitrary number of arguments (that are not functions) and then have each of those arguments get wrapped in the same function, and then that list of functions gets passed to juxt in place of funcs in my multi-any-filter function above.
Thanks for any tips!
(defn evenly-divisible? [x y]
(zero? (mod x y)))
(defn multi-any-filter [col & nums]
(let [partials (map #(fn [x] (evenly-divisible? x %)) nums)
f (apply juxt partials)]
(filter #(some true? (f %)) col)))
I coudn't use partial because it applies the arg in the first position of the fn. We want it in the second position of evenly-divisible? We could re-arrange in evenly-divisible? but then it would not really look correct when using it standalone.
user=> (reduce + (multi-any-filter (range 1 1000) 3 5))
233168

Clojure : Return value being evaluated

*Simple question : Why does this function throw an exception when evaluated ? *
In the case where there is a duplicate in the string , there is a Class cast exception thrown upon finding the duplicate.
In the case where the string has no duplicates, a NullPointerException is thrown.
*The Code *
(defn first-duplicate-char [str-in]
(loop [list-Rem (seq str-in) set-Seen (set [])]
(print (type list-Rem) " " list-Rem (next list-Rem) "\n")
(if (= 0 (count str-in))
nil
(if (some #(= (first list-Rem) %) set-Seen)
(first list-Rem)
(recur
(seq (next list-Rem))
(conj set-Seen (first list-Rem)))))))
Your problem is that (= 0 (count str-in)) never changes, so you eventually try to call first on nil. [EDIT: I'm wrong, your code actually works as is -- that if statement is just a no-op. I hope you enjoy the rest of this answer anyway.]
Instead, you should be calling next (not rest) on list-Rem in the recur and using list-Rem directly in the if test, using the property of next that returns nil for an empty seq. Here's how I would rewrite your code:
(defn first-duplicate [in]
(loop [seen #{}
remain (seq in)]
(when-let [[head & tail] remain]
(if (contains? seen head)
head
(recur (conj seen head) tail)))))
Changes:
lowercasing names
no need to call seq on the output of next or rest
with sets, contains? (check for existence of key) is faster than some (run a predicate on elements until something yields a truthy value)
set literal
using when to return nil on test failure
using when-let to destructure and bind first char and rest
Stylistic changes:
names changed to be less specific (not restricted to strings, for instance)
change order of loop locals so that recur looks more like structural recursion
put loop locals on separate lines