I define a function, which takes two parameters - map and a key. The key is referenced from the map parameter decomposition
(defn myfunc [{v k} k]
v)
when I call:
(myfunc {:a 10} :a)
It surprisingly produces expected result: 10
Similar thing in the let:
(let [{v k} {:a 10} k :a] v)
fails, because k is not defined at the moment, when first part is evaluated.
My question is: why decomposition inside function parameters behaves differently compared to decomposition in let expressions?
Macroexpanding the defn
form I get the equivalent of this (removed .withMeta stuff and reformatted):
(def myfunc
(fn* myfunc
([p__11393 k]
(let* [map__11394 p__11393
map__11394 (if (seq? map__11394)
(apply hash-map map__11394)
map__11394)
v (get map__11394 k)]
v))))
So here we can see that the {v k}
map is in fact first assigned to a local variable p__11393
. Then the if
statement tests if that variable is in fact a sequence and turns it into a hash-map if so, otherwise leaves it as it is. Importantly, the value assigned to k
is looked up in the map after all of this happens, thus this works without error (and also would if :a
wasn't in the map, get
returns nil
in that case).
On the other hand macroexpanding the let
form I get
(let*
[map__11431
{:a 10}
map__11431
(if (seq? map__11431) (apply hash-map map__11431) map__11431)
v
(get map__11431 k)
k
:a]
v)
and here we can see that v
gets the result of (get map__11431 k)
, but k
isn't defined at this point yet, hence the error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With