How clojure map and keyword could be a function [duplicate]

本小妞迷上赌 提交于 2019-12-12 16:45:47

问题


In clojure, you can use map data structure or the keyword as a function to look up the map.

(let [m {:foo "bar"}]
  (get m :foo) ; -> "bar"
  (:foo m)     ; -> "bar"
  (m :foo))    ; -> "bar"

All of these expression returns the value "bar". Implementation wise, how is it possible to use map or the keyword as a function? Is this a special case built into a clojure interpreter, or is it something I could re-create with the language? What is actually happening under the hood?


回答1:


It's all done with normal java under the hood.

There is an interface called iFn that anything in Clojure that wants to be called as a function can implement. It's up to that thing to decide what to do when called.

  • Keywords choose to look them selves up in a collection passed as the first argument.
  • Maps choose to look up the argument passed as a key in themselves.
  • Symbols also look them selves up in a collection. Much like keywords.
  • Vars make a function call to whatever function they contain, using whatever arguments they where passed. And they use this same interface to do it.



回答2:


Just to show you how this is possible in any language that has first class functions -- JavaScript example below; run it to see the results!

const map = x => a =>
  a === undefined ? x : a(map(x))

const get = m => a =>
  a(m)

const accessor = k => m =>
  m()[k]

// make accessor
const foo = accessor('foo')

// make map
let m = map({foo: 'bar'})

// test expressions
// get applied to map and accessor:
console.log(get (m) (foo)) // bar

// accessor applied to map:
console.log(foo (m))       // bar

// map applied to accessor:
console.log(m (foo))       // bar


来源:https://stackoverflow.com/questions/43861384/how-clojure-map-and-keyword-could-be-a-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!