say I have a function like this:
(defn my-f [a & [b]]
(if (nil? b)
(my-other-f a)
(my-other-f a b)))
This of course is a simplification. It's a wrapper function for another function - and in reality a is processed inside this function. If the optional argument b is not passed to my-f, it should also not be passed to my-other-f.
I was thinking of another way to achieve this:
(defn my-f [a & [b]]
(apply my-other-f (make-list-of-not-nil-entries a b)))
Is there maybe a built-in function doing this job?
Example
Sometimes, being too abstract is confusing, so I'm providing the real case here. The following ClojureScript code works, it's purpose is obviously to try different browser-specific options in order to get a "webgl" context from an HTML canvas element.
(defn create-ctx [canvas & [options]]
(some (if options
#(.getContext canvas % (clj->js options))
#(.getContext canvas %))
["webgl" "experimental-webgl" "webkit-3d" "moz-webgl"]))
The given Canvas element's method getContext awaits actually one argument, and another one which is optional. The above wrapper functions has the same arity.
I just wanted to see, if there is a quick way to avoid the explicit switch for the 1 and the 2 arity function call.
I would argue that your first solution is much more readable and explicit about its intention. It will also have much better performance than the one with apply
.
If you still want to go with apply
, the shortest solution using clojure.core
would be:
(remove nil? [a b])
Or
(keep identity [a b])
Or
(filter some? [a b])
I am not aware of any built in function which takes varargs and returns a seq of only non nil elements. You could create one:
(defn non-nils [& args]
(remove nil? args)
Or use ignoring-nils
from flatland.useful.fn
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With