69

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??

Steve Kuo
  • 61,876
  • 75
  • 195
  • 257
  • 10
    You want a not-nil? Easily done: `(def not-nil? (comp not nil?))` – Charles Duffy Aug 07 '12 at 21:39
  • 8
    You should accept [liwp's answer](http://stackoverflow.com/a/24043448/405550). A lot of people arriving here from Google won't scroll past the accepted answer to find out that the opposite of `nil?` is `some?` – Zaz Jul 29 '16 at 04:56

9 Answers9

105

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)
liwp
  • 6,746
  • 1
  • 27
  • 39
53

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 
Brad Koch
  • 19,267
  • 19
  • 110
  • 137
Arthur Ulfeldt
  • 90,827
  • 27
  • 201
  • 284
19

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")
trincot
  • 317,000
  • 35
  • 244
  • 286
Jouni K. Seppänen
  • 43,139
  • 5
  • 71
  • 100
18

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)) 
   ... 
   ...)
mikera
  • 105,238
  • 25
  • 256
  • 415
  • 2
    Isn't this answer exactly the opposite? (not "foostring") => false is opposite what I would expect from (not-nil? "foostring") also I would expect (not-nil? nil) to return false not true. – mikkom Dec 03 '13 at 18:57
7

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?))

Alexander Putilin
  • 2,262
  • 2
  • 19
  • 32
6

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)
Mars
  • 8,689
  • 2
  • 42
  • 70
4

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
tdmadeeasy
  • 306
  • 1
  • 7
2

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.

mikera
  • 105,238
  • 25
  • 256
  • 415
1

One more option:

(def not-nil? #(not= nil %))
Alex
  • 185
  • 7