Steve Kuo
Steve Kuo

Reputation: 63084

Clojure not nil check

In Clojure nil? checks for nil. How does one check for not nil?

I want to do the Clojure equivalent of the following Java code:

if (value1==null && value2!=null) {
}

Follow-up: I was hoping for a not nil check instead of wrapping it with not. if has a if-not counterpart. Is there such a counterpart for nil??

Upvotes: 73

Views: 61495

Answers (9)

Alex
Alex

Reputation: 183

One more option:

(def not-nil? #(not= nil %))

Upvotes: 0

Jouni K. Seppänen
Jouni K. Seppänen

Reputation: 44118

If you are not interested in distinguishing false from nil, you can just use the value as the condition:

(if value1
   "value1 is neither nil nor false"
   "value1 is nil or false")

Upvotes: 19

liwp
liwp

Reputation: 6926

After Clojure 1.6 you can use some?:

(some? :foo) => true
(some? nil) => false

This is useful, eg, as a predicate:

(filter some? [1 nil 2]) => (1 2)

Upvotes: 114

Mars
Mars

Reputation: 8854

If you want your test to return true when given false, then you need one of the other answers here. But if you just want to test that returns a truthy value whenever it's passed something other than nil or false, you can use identity. For example, to strip nils (or falses) from a sequence:

(filter identity [1 2 nil 3 nil 4 false 5 6])
=> (1 2 3 4 5 6)

Upvotes: 6

mikera
mikera

Reputation: 106351

In Clojure, nil counts as false for the purposes of conditional expressions.

As a result (not x) works actually works exactly the same as as (nil? x) in most cases (with the exception of boolean false). e.g.

(not "foostring")
=> false

(not nil)
=> true

(not false)  ;; false is the only non-nil value that will return true
=> true

So to answer your original question you can just do:

(if (and value1 (not value2)) 
   ... 
   ...)

Upvotes: 18

Arthur Ulfeldt
Arthur Ulfeldt

Reputation: 91544

Another way to define not-nil? would be using the complement function, which just inverts the truthyness of a boolean function:

(def not-nil? (complement nil?))

If you have several values to check then use not-any?:

user> (not-any? nil? [true 1 '()])
true
user> (not-any? nil? [true 1 nil])
false 

Upvotes: 53

tdmadeeasy
tdmadeeasy

Reputation: 306

You can try when-not :

user> (when-not nil (println "hello world"))
=>hello world
=>nil

user> (when-not false (println "hello world"))
=>hello world
=>nil

user> (when-not true (println "hello world"))
=>nil


user> (def value1 nil)
user> (def value2 "somevalue")
user> (when-not value1 (if value2 (println "hello world")))
=>hello world
=>nil

user> (when-not value2 (if value1 (println "hello world")))
=>nil

Upvotes: 4

mikera
mikera

Reputation: 106351

If you want a not-nil? function, then I'd suggest just defining it as follows:

(defn not-nil? 
  (^boolean [x]
    (not (nil? x)))

Having said that it is worth comparing the usage of this to the obvious alternative:

(not (nil? x))
(not-nil? x)

I'm not sure that introducing an extra non-standard function is worth it for saving two characters / one level of nesting. It would make sense though if you wanted to use it in higher order functions etc.

Upvotes: 2

Alexander Putilin
Alexander Putilin

Reputation: 2342

condition: (and (nil? value1) (not (nil? value2)))

if-condition: (if (and (nil? value1) (not (nil? value2))) 'something)

EDIT: Charles Duffy provides correct custom definition for not-nil?:

You want a not-nil? Easily done: (def not-nil? (comp not nil?))

Upvotes: 7

Related Questions