Quoting from Joy of Clojure, section 4.3.1--
Because keywords are self-evaluating and provide fast equality checks, they\'re almost always us
Keywords implement IFn,
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Keyword.java
and its invoke method handles calling get.
Keywords are functions, in every way. There is no reader magic involved, as you will see if you try (let [m {:humans 100}, k :humans] (k m))
. I hope you'll agree there's no way the reader could turn this into a get (the compiler could, but you can pretend that I've made the value of k
depend on an if expression that the compiler can't predict, such as user input).
Because Clojure's core data types are interfaces, and Java objects can implement many interfaces, a piece of data can have multiple types. Is it a keyword? Yes. Is it a function? Also yes:
user> (keyword? :k)
true
user> (ifn? :k)
true
user> (.invoke :k {:k 1})
1
Citation from official documentation:
Keywords implement IFn for invoke() of one argument (a map) with an optional second argument (a default value). For example (:mykey my-hash-map :none) means the same as (get my-hash-map :mykey :none). See get.
And Clojure can call keyword as function, because it implements same interface as function. The same is for symbols...