clojure: What's the use of the #'/(var …) form?

ぐ巨炮叔叔 提交于 2019-12-21 04:39:28

问题


In the compojure library in the core namespace, I see the following form:

(defn- compile-route
  "Compile a route in the form (method path & body) into a function."
  [method route bindings body]
  `(#'if-method ~method
     (#'if-route ~(prepare-route route)
       (fn [request#]
         (let-request [~bindings request#]
           (render (do ~@body) request#))))))

and

(defmacro GET "Generate a GET route."
  [path args & body]
  (compile-route :get path args body))

Further up in the file, the if-method and if-route functions are defined with defn-s.

I don't understand the meaning of the #' in this compile-route function though. The docs for (var ...) says:

The symbol must resolve to a var, and the Var object itself (not its value) is returned. The reader macro #'x expands to (var x).

But to me, in the context of what is happening (ie being called from a defmacro), it just sounds like it means the value of the symbol will be returned, which is the same as what substitutability sounds like:

(def x 5)
(+ x 7)
-> 12

ie, (+ x 7) expands to, or is the same as, (+ 5 7)

What am I missing here?


回答1:


After looking at this for a while, I'm starting to suspect that it has something to do with the fact that the if-method and if-route functions are actually private ((defn- if-route ...)).

Also, for macros, when you do the back-tick quote (" ` ") you are actually getting the fully-namespace-specified symbol in the final expansion:

`(+ 2 3)

would expand to

(clojure.core/+ 2 3)

Since these methods are private, they won't be accessible in the normal expansion, therefore the var function is used, to get to the symbol that holds a reference to the actual function that must be invoked at this point in the expansion.




回答2:


ring-reload can reload var definitions from files that you keep modifying during development. Since you pass on a (var ...), it is resolved every time you try to read it, and as a consequence the reloaded vars can be re-read on every request. This leads to interactive web development (without needing to compile etc.) If you don't use (var ...) and rather pass the value directly then the reloaded vars will not be passed to the ring URI handlers and hence you cannot simply modify-and-run your code.

Check this blog entry for example:

http://charsequence.blogspot.com/2010/09/interactive-web-development-with.html



来源:https://stackoverflow.com/questions/5462166/clojure-whats-the-use-of-the-var-form

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