Written by
Aaron Bell
on
on
`alter-var-root` changes what a variable points to (vs. Clojure's default of spawning a new variable/value binding)
(Yell at me on Twitter, @AttentionAaron, if this is wrong.)
Understanding the Integrant REPL library source code required that I know alter-var-root
, so here’s how I understand it.
When programming, we decide meaning of symbols through “binding” or “assignment” or “pointing”. The first two feel bidirectional, which doesn’t seem the case; you can’t look up the variable through the value, so the term pointing feels the most precise.
You can do three things regarding a pointer and the pointee:
- The best, least confusing is thing to leave it alone and create an entirely new pointer and pointee–never changing neither the original variable nor value. Clojure defaults to this. Functions will return a new binding in the current or more local scope.
- Next best is to change the pointee. That way when the value changes, and other things point to it, it’s very well understood that all will return the same value. Clojure does this with atoms using
swap!
andreset!
- Last resort is to change where the pointer points to, leaving the pointee unaffected. Clojure achieves this with
alter-var-root
(example) anddef
. I speculate that this reduces overhead and improves performance at high cognitive expense.
For the third, James Reeves (weavejester) manages configuration and component state with in the Integrant REPL library.
The Clojure core team members use it to create a list of namespaces whose source code’s changed to queue it for reloading.