Clojure, alter-var-root, and constantly

David Rupp
2 min readApr 23, 2015

--

A minor Clojure mystery solved.

Reading other people’s Clojure code (which I highly recommend doing, by the way), I occasionally run across this idiom:

And I wonder why not just set the value of thing to nil directly, say with another def?

While this would certainly work, it’s considered kind of gauche, particularly if the second def were to appear nested inside some other code. The second def happens to have the effect of updating the value of an existing thing, but we really should think of def as defining things. We expect things to be defined once, and then their values later altered, if need be.

That’s where alter-var-root comes in. Given a thing that has been defined (Clojure calls this a “var”) with some value (Clojure calls this the “root” value), alter-var-root is the idiomatic way of changing that value. But it’s not as simple as just supplying the new value. Clojure wants to calculate the new value of the var, by applying a function to the current value.

So what if the new value isn’t a function of the old value? What if you want the new value to be something specific no matter what the old value is?

That’s where constantly comes in. You can’t just say “(alter-var-root #’thing nil)”, because nil is not a function. alter-var-root needs a function. So you need to give it a function that always returns nil no matter what its argument is. The value of (constantly nil) is a function that returns nil no matter what its argument is. Problem solved!

The thing about constantly is that it’s actually more general than we need. The function applied by alter-var-root will alway receive exactly one argument — the old value of the var. The function returned by constantly can take any number of arguments; including 1, but also including 0, or 15, or …

You might think that we could use Clojure’s function literal syntax to be more explicit, but it is surprisingly unhelpful here. This is because of how function literals deal with arity. The arity of a literal function is determined by the highest-numbered parameter referred to in the function body.

We need a function of arity 1, so we need to include an explicit “%1” in our literal function body. But where can we put that and also return a result of nil?

So it’s probably best just to get used to the idiom, but now with a deeper understanding of how and why it works, not just that it works.

--

--

David Rupp

IMDb Ad Tech by day. Polyglot by night. Ex-ThoughtWorks, Ex-AWS.