Is there a function in Clojure that always returns nil no matter what the input is?
I know I could write (fn [_] nil) but is there a built-in function?
You can use constantly to return a function which always returns the given value e.g.
(constantly nil)
Note the returned function takes an arbitrary number of parameters while yours only allows one.
constantly is the function you are looking for:
((constantly nil) 2)
=> nil
Related
I'm trying to do a simple if statement that checks if a variable is nil or not.
(defun test (input)
(let ((testvar (first input)))
(if (not nil testvar)
(do this)
(do that))))
Could anyone explain the proper syntax to me?
Since nil is equivalent to the boolean value false, there is no need to compare to it explicitly.
A simple
(if testvar
(...)
(...))
will do the job. You only need not if you want to check for the opposite, e.g. if you want to check that a variable is not nil:
(if (not testvar)
(...)
(...))
Apart from that, there is also a predicate function called null that you might use. It is basically meant for checking whether a given list is empty, but since the empty list is equivalent to nil, it will work (as the examples on the linked page point out):
(null '()) => T
(null nil) => T
(null t) => NIL
(null 1) => NIL
Anyway, this basically only moves the problem one layer up ;-)
Do you want to check if the variable is nil or if it is not nil?
For not nil: (if v ... ...)
For nil: (if (not v) ... ...)
There are (in CL) many variations which are all logically the same but may indicate intent better: (if (null v) ... ...) if the same as the second case above but might indicate to the reader that you are looking for `()‘ instead of logical falsity (ie an empty list). And there are plenty of other variations.
jkiiski was right:
Just (if (not testvar) ...). Or put the true branch first and do (if testvar ...)
Why do the following statements return different results? And further, how would one write the second statement to receive the expected result of false?
(clojure.core/and false true)
=> false
((resolve 'clojure.core/and) false true)
=> true
The kind folks at #clojure on freenode helped me with an answer.
First, one should try to avoid resolving macros at run-time.
Second, the macro function is implemented as a function that takes in two parameters, besides of the any (&) args. Hence, the correct way to write the second statement above would be
((resolve 'clojure.core/and) nil nil false true) =>
**(clojure.core/let [and__3973__auto__ false] (if and__3973__auto__ (clojure.core/and true) and__3973__auto__))**
Since we are still using a macro, it simply will expand it to code, instead of returning an actual value.
The reason AND is implemented as a macro, is to make short-circuiting possible.
You can see from the REPL:
(defmacro and
"Evaluates exprs one at a time, from left to right. If a form
returns logical false (nil or false), and returns that value and
doesn't evaluate any of the other expressions, otherwise it returns
the value of the last expr. (and) returns true."
{:added "1.0"}
([] true)
([x] x)
([x & next]
`(let [and# ~x]
(if and# (and ~#next) and#))))
Without the macro, an AND function would evaluate all of the predicate given to it without short-circuiting.
In my particular case, this is exactly what I needed; both for AND and OR non short-circuiting functions.
Here follows both functions in case anyone ever needs them:
(defn and* [& xs] (every? identity xs))
(defn or* [& xs] (not= (some true? xs) nil))
Can someone explain the behavior in the Clojure code below?
I don't get it.
Does Clojure somehow replace or "optimize" function arguments? Why does calling a function with a single nil argument result in an ArityException?
(defn foo [bar] (reduce #(%1) bar))
(foo nil)
-> ArityException Wrong number of args (0) passed to: test$foo$fn clojure.lang.AFn.throwArity (AFn.java:437)
See (doc reduce):
[...]
If coll contains no
items, f must accept no arguments as well, and reduce returns the
result of calling f with no arguments.
[...]
Here coll is nil, which is effectively being treated as a collection containing no items (as it usually is in similar contexts), and f is #(%1).
Thus #(%1) is being called with no arguments and ends up throwing the exception you see.
for example,
> (some #{nil} #{nil 1 2 3})
nil
> (some #{} #{nil 1 2 3})
nil
I know I could use
(some nil? #{nil 1 2 3})
to check nil value. I can't think of any good example at the moment.
But generally, when nil is returned, how do I determine if nil means nothing is found or the value nil is found?
nil is just a value, and its meaning depends on context.
It's just like all other values in that regard: the only thing to be aware of is that it is falsy, i.e. counts as false in conditional expressions.
Three particular cases to be aware of:
nil is the return value used to indicate an empty sequence, e.g. in (seq [])
nil is often used as a return value to indicate false, e.g. in (or false nil)
nil is returned by default when a map lookup can't find a given key, e.g. in ({:a 1} :b)
These cases can on occasion cause ambiguity: if so then you need to use a different function. Your example is a good one:
(some #{nil} #{1 2 3}) => nil (failure - no result found)
(some #{nil} #{nil 1 2 3}) => nil (success - nil result found!!!)
In this case you've simply chosen the wrong function: you can't use the set #{nil} to detect nils.... instead you can just use nil? or you could even do something fancy with an alternative return value like #(get #{nil} % :not-found)
Isn't this a question of the question you're asking, rather than anything particular to Clojure ?
You could ask:
> (filter nil? #{nil 1 2 3})
> (nil)
which tells you there was one nil in the set; you get what you ask for - you asked an ambiguous question and got a suitably ambiguous response.
In Clojure what is the idiomatic way to test for nil and if something is nil then to substitute a value?
For example I do this a lot:
let [ val (if input-argument input-argument "use default argument")]
: but I find it repetitive having to use "input-argument" twice.
just use or:
(or input-argument "default")
Alex's suggestion of "or" is indeed the idiomatic way to rewrite your example code, but note that it will not only replace nil values, but also those which are false.
If you want to keep the value false but discard nil, you need:
(let [val (if (nil? input-argument) "use default argument" input-argument)]
...)
If you only bind the variable to do get the right value and not to use it twice there is a other way you can do it. There is a function in core called fnil.
You call fnil with the function you want to call and the default argument. This will return a function that will replace nils with the default value you provided.
The you can do one of the things depending on what you want. Creat a local function.
(let [default-fn (fnil fn-you-want-to call "default-argument")]
(default-fn input-argument))
In somecases (where you always have the same default argument) you can move to logic to do this out of your code and put it where to original function was (or wrap the function in case it in a other library).
(defn fn-you-want-to-call [arg] ....)
(def fn-you-want-to-call-default (fnil fn-you-want-to-call "default-argument"))
Then in your code its reduced to just
(fn-you-want-to-call-default input-argument)
More you can find here:
http://clojuredocs.org/clojure_core/clojure.core/fnil
When the expected value is a boolean I recommend using an util fn.
(defn- if-nil [default val]
(if (nil? val)
default
val))
(if-nil true (possible-false input))