# Clojure higher-order functions explained: fnil

Published: 2021-03-19

#clojure

Checkout the index for the full series.

## Source code

It’s better to read the source code first because source code don’t lie. Here’s the source of fnil in clojure 1.10.1:

``````(defn fnil
"Takes a function f, and returns a function that calls f, replacing
a nil first argument to f with the supplied value x. Higher arity
versions can replace arguments in the second and third
positions (y, z). Note that the function f can take any number of
arguments, not just the one(s) being nil-patched."
:static true}
([f x]
(fn
([a] (f (if (nil? a) x a)))
([a b] (f (if (nil? a) x a) b))
([a b c] (f (if (nil? a) x a) b c))
([a b c & ds] (apply f (if (nil? a) x a) b c ds))))
([f x y]
(fn
([a b] (f (if (nil? a) x a) (if (nil? b) y b)))
([a b c] (f (if (nil? a) x a) (if (nil? b) y b) c))
([a b c & ds] (apply f (if (nil? a) x a) (if (nil? b) y b) c ds))))
([f x y z]
(fn
([a b] (f (if (nil? a) x a) (if (nil? b) y b)))
([a b c] (f (if (nil? a) x a) (if (nil? b) y b) (if (nil? c) z c)))
([a b c & ds] (apply f (if (nil? a) x a) (if (nil? b) y b) (if (nil? c) z c) ds)))))``````

## Usages

Simply put, fnil patches functions to handle nil arguments. Usually this is because you are using functions that you do not maintain and want them to handle `nil`s in your particular use cases rather than just barfing out NPEs.

Personally, `fnil` has become increasingly handy ever since I come to be more liberal on passing `nil`s as real values in the front-end presentation logic. (See my other article about nil busting here.)

## Examples

There are a couple of great examples by the Clojure community on clojuredocs.org’s fnil page. Please go check it out for the examples!

## My use cases

This is my growing list of use cases where I stumble upon and found `fnil` useful ;)

### Python defaultdict in Clojure

Being a more Object-oriented language than functional, the way Python deal with inserting default value in a hash-table (or `dict`) through the object, defaultdict. Example:

``````>>> import collections
>>> d = collections.defaultdict(list)
>>> d['yellow'].append(1)
>>> d
defaultdict(<class 'list'>, {'yellow': [1]})``````

The more functional approach to the problem can be done using `fnil` in Clojure. Instead of defining the new behavior of an object, just create a function that knows what to do with `nil`:

``````(def conj* (fnil conj []))
(update {} :yellow conj* 1)
;; => {:yellow [1]}

;; Or, inline the function
(update {} :yellow (fnil conj []) 1)
;; => {:yellow [1]}``````

Credits to clojuredocs’s user Dimagog’s example. It was my initial inspiration.

### Identity fallback

Again from my previous article about nil busting here:

``````(defn self-or [other] (fnil identity other))

(->> [nil nil nil nil nil nil nil nil nil nil nil nil nil "Batman!"]
(map (self-or "na"))
(clojure.string/join ", "))``````

### Retrofitting clojure string functions

Most of the `clojure.string` functions don’t like `nil`s and will throw NPE at you. `fnil` to the rescue!

``````(require '[clojure.string :as str])
(sort-by (fnil str/lower-case "") ["hi" nil "ho"])
;; => (nil "hi" "ho")``````