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.