Clojure nil busting one-liners
To remove all
nils from a seq:
To transform a seq and remove
nils from its result:
To replace all
nils with a fallback value from a seq:
nil is a value in Clojure that represents “the absence of a value”. Working with
nils is quite common in Clojure. Most of the core library functions deal with
nils elegantly, and very consistent. Overtime, it’s quite easy to develop the intuitions that tell you how
nils will flow through the functions. However, in some cases, which I’ll explain in the later sections below, I do need to take some actions to deal with
nils. Fortunately, we are in a great position with all the tools in the
Most of the time, just do nothing
In most cases, we simply don’t need to do anything since so many core functions work with
Because of this behavior, functions using the seq abstraction (
reduce, etc.) works out of the box even when the seq contains
However, when functions do give up on
nils, we need other strategies.
When piping a value through a series of transformations, if one transformation turns the value into
nil, the rest of the transformations might fail. For example:
In this case we can simply swap the threading macros
->> with their early-termination variants:
However, this only works if the step yields
nil. What if we get something like this:
In this case, we’ll need to bust those
nils from the seq.
When there’s no need to preserve those
remove them from the seq.
remove is equivalent to
keep when we want to remove the
nils from a series of transformations:
In some case, we do want to preserve the
nils (perhaps because we need the correct count of the seq, or the
nils are something meaningful later down the pipe.)
My first thought was using the
or form to replace each
nil with a fallback value. However, creating a partial function doesn’t work because:
partialcannot take macros like
oras arguments, and
- the order of the arguments doesn’t work out for us, i.e.
(partial or a-fallback)is not what we want.
or work, we need to create a function:
#(or % a-fallback). However, creating an anonymous function seems an overkill to me. I prefer function compositions whenever possible, especially for a conceptually simple functions like this. Here’s solution I came up with using
I never did find any real use case for
fnil until this tweet. This whole article is actually just an excuse for sharing the usage of
fnil shown in the last code snippet, which I’m pretty excited about! I did find another cool usage of
fnil soon after. I’ll write more about
fnil and other cool thing you can do with higher-order function in the future. Thanks for reading!