Reputation: 496
In clojure you can use both maps and keys as look up functions hence
({:a 1 :b 2} :a)
and (:a {:a 1 :b 2})
are both viable lookup functions.
Why then can you use a map as a lookup function for a compound-key but not the other way around?
This means ({[:compound :mebaby] 1} [:compound :mebaby]})
will return 1
, but ([:compound :mebaby] {[:compound :mebaby] 1})
will throw an error.
Upvotes: 1
Views: 274
Reputation: 52540
Your assumption that you can use a key as a lookup function is incorrect. You can use a keyword as a lookup function. In your example :a
is a keyword. And so it can be used as a lookup function. But [:compound :mebaby]
is not a keyword, that's a vector. Vectors can't be used as lookup functions.
Upvotes: 0
Reputation: 1109
The reason is that: your compound-key is no longer a keyword. It is now a vector, though still an IFn
, it only takes integers, say i
, as arguments, returning the i
th element of the vector.
I suspect what you really want is to extract value from a nested map, like extracting the String "c" from {:a {:b "c"}}
. If so, these two forms are equivalent:
(get-in {:a {:b "c"}} [:a :b])
;=> "c"
((comp :b :a) {:a {:b "c"}})
;=> "c"
Upvotes: 0
Reputation: 3014
Keywords implement IFn
as one of their features to make them convenient to use as keys. The fn they implement is a lookup for themselves in an associative structure argument. This is not the case for collections like your vector because they implement IFn
to do lookup in themselves at the argument key.
So ({[:compound :mebaby] 1} [:compound :mebaby]})
asks the map what the value is for the key [:compound :mebaby]
, which exists. But ([:compound :mebaby] {[:compound :mebaby] 1})
asks the vector what the value at the index {[:compound :mebaby] 1}
is. That's not an integral number, so it can't be an index/key in a vector and throws an error.
Upvotes: 2