Lately I was wondering how to set variables in a specific order in a :or
clause in Clojure’s destructuring mini language. I needed to set a key b to
the return value of a function f that is dependant on a key a.
My first thought was that the :or {} syntax wouldn’t obey the order (since it
is a map), so I’ve used :or []. But that doesn’t work at all, it does not do
anything, both get bound to nil, as if no :or was specified.
When using :or {} it magically worked, but how can you trust that the order
is always correct, since maps are inherently unordered?
Turns out, the order in which keys are taken from the :or map depends on the
:keys vector! Compare specifying a before b, which works as expected:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
with specifying b before a which fails since a is not yet known.
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
This behaviour works well but it was rather unexpected. It kinda does explain
why the :keys takes a vector as a value and not a set, because the order is
important.
Thanks to Jan Stępień for getting to the bottom of this.