Why does using keywords or symbols as functions to lookup values from maps work?

后端 未结 3 965
你的背包
你的背包 2020-12-06 04:10

Quoting from Joy of Clojure, section 4.3.1--

Because keywords are self-evaluating and provide fast equality checks, they\'re almost always us

相关标签:
3条回答
  • 2020-12-06 04:53

    Keywords implement IFn,

    https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Keyword.java

    and its invoke method handles calling get.

    0 讨论(0)
  • 2020-12-06 04:55

    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
    
    0 讨论(0)
  • 2020-12-06 05:13

    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...

    0 讨论(0)
提交回复
热议问题