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 ...)
Related
(def mine '(a b c))
(def yours '(a b))
(remove yours mine)
; should return (c)
I was advised to use remove in another thread but it doesn't work.
Anyone can advise?
Assuming you want to remove from mine every element that also exists in yours, there are a few approaches. You can convert the lists to sets and use difference, like this:
(require '[clojure.set :refer [difference]])
(def mine '(a b c))
(def yours '(a b))
(difference (set mine) (set yours))
;; => #{c}
But this does not preserve the order of elements that remain from mine. If you want to preserve the order, you can instead use remove. To do that, we first define a yours? predicate that will return true for an element iff that element occurs in yours:
(def yours-set (set yours))
(def yours? (partial contains? yours-set))
If our set yours only contains truthy values like that are neither nil nor false, we could define it like (def yours? (set yours)) since a set implements the IFn interface but this approach will not work if yours contains elements such as nil or false as #amalloy pointed out.
(remove yours? mine)
;; => (c)
The above code means that we remove every element from mine for which yours? evaluates to true. Yet another, more verbose approach, is to use the opposite of remove, that is filter, and passing in the opposite of the predicate.
(filter (complement yours?) mine)
;; => (c)
but I see no gain of that more verbose approach here.
If you know that you want a vector as a result, you can instead use into, passing in a removeing transducer as argument.
(into [] (remove yours?) mine)
;; => [c]
contains? is a horrible misnamer in Clojure in my view. (No, it does NOT check, whether an element is contained in a collection! It just checks whether for a key (an index or key) there exist a value in the collection.)
Use some in combination with #{} to check for membership in a collection!
(remove #(some #{%} yours) mine)
;; => (c)
Or:
(defn in? [coll x] (some #{x} coll))
(remove #(in? yours %) mine) ;; => {c}
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))
How can I check if a value is NaN? I'd prefer a solution that can be used in Clojure too without much extra stuff (so I don't want to use an external library, such as underscore). Here is what I tried
(number? js/NaN) ;=> true, well I'd expect false
(= js/NaN (js/parseInt "xx")) ;=> false
(= js/NaN js/NaN) ;=> false, even worse
; This is the best I could come up with
(defn actual-number?
[n]
(or (> 0 n) (<= 0 n)))
You shouldn't compare NaN's - they're always unequal. You should be able to use javascript's built-in isNaN function like
(js/isNaN x)
You can use isNaN js function:
(js/isNaN ..)
Be aware that
(js/isNaN [1,2])
returns true. There are other many cases where js/isNaN does not correspond to what one expects.
If you're using underscore.js in the browser, you can delegate to (.isNaN js/_ ..) instead.
Otherwise, the following function should to the trick:
(defn isNaN [node]
(and (= (.call js/toString node) (str "[object Number]"))
(js/eval (str node " != +" node ))))
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))
In Common Lisp you use the (null x) function to check for empty lists and nil values.
Most logically this maps to
(or (nil? x) (= '() x))
In clojure. Can someone suggest a more idiomatic way to do it in Clojure?
To get the same result for an empty list in Clojure as you do in Common Lisp, use the empty? function. This function is in the core library: no imports are necessary.
It is also a predicate, and suffixed with a ?, making it a little clearer what exactly you're doing in the code.
=> (empty? '())
true
=> (empty? '(1 2))
false
=> (empty? nil)
true
As j-g faustus already noted, seq can be used for a similar effect.
seq also serves as test for end,
already idiomatic
(when (seq coll)
...)
From clojure.org lazy
It works because (seq nil) and (seq ()) both return nil.
And since nil means false, you don't need an explicit nil test.