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.
Related
I'm hoping the explanation will give me better insight into the advantages of using macros.
In a function, all arguments are evaluated before its invocation.
This means that or as a function cannot be lazy, whereas a macro can rewrite or into an if statement that only evaluates branches when it's necessary to do so.
A bit more concretely, consider:
(or (cached-lookup) (expensive-operation))
...what it gets rewritten into looks like:
(let [or__1234__auto (cached-lookup)]
(if or__1234__auto
or__1234__auto
(expensive-operation)))
...such that we only evaluate (expensive-operation) if the return value of (cached-lookup) is nil or false. You couldn't do that with a function while implementing regular JVM calling conventions: expensive-operation would always be evaluated, whether or not its result is needed, so that its result could be passed as an argument to the function.
Incidentally, you can implement a function in this case if you take zero-argument functions as your arguments. That is to say, you can do this:
(defn or*
([] false) ; 0-arg case
([func-one] (func-one)) ; 1-arg case
([func-one func-two] ; optimized two-arg case
(let [first-result (func-one)]
(if first-result
first-result
(func-two))))
([func-one func-two & rest] ; general case
(let [first-result (func-one)]
(if first-result
first-result
(apply or* func-two rest)))))
When you must implement a macro, it's often helpful to have it generate "thunks" (anonymous functions), and pass them to higher-order functions such as this one; this substantially aids composability, as a function can be wrapped, modified, or called using higher-level functions such as partial in ways a macro cannot.
Guess what would happen if or and and were functions in this case?
(defn some [f l]
(and (seq l)
(or (f (first l))
(some f (rest l)))))
If you guessed it would never terminate you are right! In fact both of them are macros expanding to if. Macros allows us to make code that gets translated to something else before it's run so a macro doesn't have access to values, just the code.
What's the (most) idiomatic Clojure representation of no-op? I.e.,
(def r (ref {}))
...
(let [der #r]
(match [(:a der) (:b der)]
[nil nil] (do (fill-in-a) (fill-in-b))
[_ nil] (fill-in-b)
[nil _] (fill-in-a)
[_ _] ????))
Python has pass. What should I be using in Clojure?
ETA: I ask mostly because I've run into places (cond, e.g.) where not supplying anything causes an error. I realize that "most" of the time, an equivalent of pass isn't needed, but when it is, I'd like to know what's the most Clojuric.
I see the keyword :default used in cases like this fairly commonly.
It has the nice property of being recognizable in the output and or logs. This way when you see a log line like: "process completed :default" it's obvious that nothing actually ran. This takes advantage of the fact that keywords are truthy in Clojure so the default will be counted as a success.
There are no "statements" in Clojure, but there are an infinite number of ways to "do nothing". An empty do block (do), literally indicates that one is "doing nothing" and evaluates to nil. Also, I agree with the comment that the question itself indicates that you are not using Clojure in an idiomatic way, regardless of this specific stylistic question.
The most analogous thing that I can think of in Clojure to a "statement that does nothing" from imperative programming would be a function that does nothing. There are a couple of built-ins that can help you here: identity is a single-arg function that simply returns its argument, and constantly is a higher-order function that accepts a value, and returns a function that will accept any number of arguments and return that value. Both are useful as placeholders in situations where you need to pass a function but don't want that function to actually do much of anything. A simple example:
(defn twizzle [x]
(let [f (cond (even? x) (partial * 4)
(= 0 (rem x 3)) (partial + 2)
:else identity)]
(f (inc x))))
Rewriting this function to "do nothing" in the default case, while possible, would require an awkward rewrite without the use of identity.
This question similar to say, In clojure, how to apply 'and' to a list?, but solution doesn't apply to my question. every? function returns just a boolean value.
or is a macro, so this code is invalid:
(apply or [nil 10 20]) ; I want to get 10 here, as if 'or was a function.
Using not-every? I will get just boolean value, but I want to preserve semantics of or - the "true" element should be a value of the expression. What is idiomatic way to do this?
My idea so far:
(first (drop-while not [nil 10 20])) ; = 10
you might be able to use some for this:
(some identity [nil 10 20]) ; = 10
Note that this differs from or if it fails
(some identity [false]) ; = nil
(or false) ; = false
A simple macro:
(defmacro apply-or
[coll]
`(or ~#coll))
Or even more abstract
(defmacro apply-macro
[macro coll]
`(~macro ~#coll))
EDIT: Since you complained about that not working in runtime here comes a version of apply-macro that works in runtime. Compare it with answers posted here: In clojure, how to apply a macro to a list?
(defmacro apply-macro-in-runtime
[m c]
`(eval (concat '(~m) ~c)))
Notice that this version utilizes that parameters are passed unevaluated (m is not evaluated, if this was a function, it would throw because a macro doesn't have a value) it uses concat to build a list containing of a list with the quoted macro-name and whatever the evaluation of form c (for coll) returns so that c as (range 5) would be fully evaluated to the list that range returns. Finally it uses eval to evaluate the expression.
Clarification: That obviously uses eval which causes overhead. But notice that eval was also used in the answer linked above.
Also this does not work with large sequences due to the recursive definition of or. It is just good to know that it is possible.
Also for runtime sequences it makes obviously more sense to use some and every?.
From a comment on another question, someone is saying that Clojure idiom prefers to return nil rather than an empty list like in Scheme. Why is that?
Like,
(when (seq lat) ...)
instead of
(if (empty? lat)
'() ...)
I can think of a few reasons:
Logical distinction. In Clojure nil means nothing / absence of value. Whereas '() "the empty list is a value - it just happens to be a value that is an empty list. It's quite often conceptually and logically useful to distinguish between the two.
Fit with JVM - the JVM object model supports null references. And quite a lot of Java APIs return null to mean "nothing" or "value not found". So to ensure easy JVM interoperability, it makes sense for Clojure to use nil in a similar way.
Laziness - the logic here is quite complicated, but my understanding is that using nil for "no list" works better with Clojure's lazy sequences. As Clojure is a lazy functional programming language by default, it makes sense for this usage to be standard. See http://clojure.org/lazy for some extra explanation.
"Falsiness" - It's convenient to use nil to mean "nothing" and also to mean "false" when writing conditional code that examines collections - so you can write code like (if (some-map :some-key) ....) to test if a hashmap contains a value for a given key.
Performance - It's more efficient to test for nil than to examine a list to see if it empty... hence adopting this idiom as standard can lead to higher performance idiomatic code
Note that there are still some functions in Clojure that do return an empty list. An example is rest:
(rest [1])
=> ()
This question on rest vs. next goes into some detail of why this is.....
Also note that the union of collection types and nil form a monoid, with concatenation the monoid plus and nil the monoid zero. So nil keeps the empty list semantics under concatenation while also representing a false or "missing" value.
Python is another language where common monoid identities represent false values: 0, empty list, empty tuple.
From The Joy of Clojure
Because empty collections act like true in Boolean contexts, you need an idiom for testing whether there's anything in a collection to process. Thankfully, Clojure provides such a technique:
(seq [1 2 3])
;=> (1 2 3)
(seq [])
;=> nil
In other Lisps, like Common Lisp, the empty list is used to mean nil. This is known as nil punning and is only viable when the empty list is falsey. Returning nil here is clojure's way of reintroducing nil punning.
Since I wrote the comment I will write a answer. (The answer of skuro provides all information but maybe a too much)
First of all I think that more importend things should be in first.
seq is just what everybody uses most of the time but empty? is fine to its just (not (seq lat))
In Clojure '() is true, so normaly you want to return something thats false if the sequence is finished.
if you have only one importend branch in your if an the other returnes false/'() or something like that why should you write down that branch. when has only one branch this is spezially good if you want to have sideeffects. You don't have to use do.
See this example:
(if false
'()
(do (println 1)
(println 2)
(println 3)))
you can write
(when true
(println 1)
(println 2)
(println 3))
Not that diffrent but i think its better to read.
P.S.
Not that there are functions called if-not and when-not they are often better then (if (not true) ...)
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))