3 ms·
Something I find strange about hashes in Clojure, is that you can access them using the key as a function. So instead of ({ :foo 1 :bar 2 } :foo) ;; => 1
by whacked_new 18y ago
Something I find strange about hashes in Clojure, is that you can access them using the key as a function. So instead of
({ :foo 1 :bar 2 } :foo) ;; => 1
You get the equivalent by doing
(:foo { :foo 1 :bar 2 }) ;; => 1
For default values:
(:baz { :foo 1 :bar 2 } 3) ;; => 3
I vaguely remember this is because keys act as functions, and hashes act as functions as well. Out of habit and similarity to other languages, I never use the key-first notation, nor can I see where it is better to use it.
- tokipin 18y agoit's likely for usage in higher-order functions. i haven't used clojure but i assume you can do something like this: (map :foo hashofhashes) which would get the element :foo of every hash in hashofhashes
- pmjordan 18y agoThat's another good point, although the alternative isn't much longer: (map #(% :foo) hashofhashes) or if % has a chance of being nil: (map #(get % :foo) hashofhashes)
- pmjordan 18y agoYep, the funcall semantics of symbols and keywords are to forward the symbol and key itself along with the arguments to the get function. I do sometimes use this notation, mostly when: - the map could be nil. (get nil :foo) and (:foo nil) will return nil, but (nil :foo) will throw an exception. - dealing with struct-maps, where the key can effectively be seen as an accessor function. (cf structs in CL) - (rarely) when the expression evaluating to the map is long and complex. A keyword in the function position (a) makes it clear that what follows must be a map or set and (b) you don't have to start counting parens.