*In short, Clojure's *`zero?`

isn't exactly like `nil?`

and `true?`

and others. It checks different numeric types and throws if given a non-numeric type.

*This post was written about Clojure 1.8.0.*

Clojure has a few functions that do equality checks, like `nil?`

, `true?`

, `false?`

, and `zero?`

. The docs all look about the same for these functions. `nil?`

"returns true if x is nil, false otherwise" and the rest look similar.

But despite similar documentation, `zero?`

is a little bit different from the rest.

Let's start by looking at `true?`

. It accepts anything as an argument; a boolean, a string, whatever.

```
(true? true) ;; true
(true? false) ;; false
(true? "str") ;; false
```

In contrast, `zero?`

throws an error if the argument isn't a number.

```
(zero? 0) ;; true
(zero? 42.0) ;; false
(zero? "str") ;; throws java.lang.ClassCastException
```

This was a little surprising to me! It's not documented and it also doesn't match the other equality checkers.

`zero?`

is also a little smarter about different numeric types. `zero?`

handles cases that a simple equality check doesn't.

```
(= 0 0) ;; true
(= 0 0.0) ;; false
(= 0 "str") ;; false
(zero? 0) ;; true
(zero? 0.0) ;; true
(zero? "0") ;; throws java.lang.ClassCastException
```

You could write a version of `zero?`

that works like `nil?`

, which won't throw on non-numeric input but will still work for various number types.

```
(defn safe-zero? [x]
(and (number? x) (zero? x)))
(safe-zero? 0) ;; true
(safe-zero? 0.0) ;; true
(safe-zero? "str") ;; false
```

`zero?`

isn't vastly more complicated than I expected, but it's a little more nuanced than I thought at first glance.