Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

read eval print loop - Clojure - difference between ' (apostrophe) and ` (backtick)

I'm fairly new to Clojure and I'm not sure I completely understand the difference between apostrophe and backtick in Clojure.

(def x 5)

;; Question 1
(+ x x)  ;; evaluates to 10
'(+ x x) ;; evaluates to (+ x x)
`(+ x x) ;; evaluates to (clojure.core/+ user/x user/x)

;; Question 2
`(~+ ~x ~x) ;; evaluates to (#<core$_PLUS_ clojure.core$_PLUS_@32ee28a9> 5 5)
  1. Correct me if I'm wrong, but it seems to me that apostrophe prevents all symbols (i.e + and x) from resolving to their respective var's, whereas backtick allows the symbols to resolve to their var's (but doesn't evaluate to the values within the var). Is this accurate?
  2. What exactly does the unquote symbol (~) do here? Is it eval'ing the var to its actual value (i.e. the + symbol to the function object and the x symbol to the number object)? If you could explain this in terms of Clojure's READ-COMPILE-EVAL phases, that would be helpful as well.
question from:https://stackoverflow.com/questions/17800917/clojure-difference-between-apostrophe-and-backtick

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When you quote a collection with ', the symbol-name will be quoted exactly as you enter it.

'(+ x x) 
=> (+ x x)
(map namespace *1)
=> (nil nil nil)
'(bingo/+ lara/y user/z)
=> (bingo/+ lara/y user/z)
(map namespace *1)
=> ("bingo" "lara" "user")

When you quote a collection with the backtick, it tries to find each symbol's namespace. If it can't find one, it uses the current namespace. If you specify a namespace, it works the same as ' with a qualified namespace.

`(+ x x)
= > (clojure.core/+ user/x user/x)
(map namespace *1)
=> ("clojure.core" "user" "user")

When you are using ~ inside ` the form will simply be unquoted. This is helpful for building macros where the macro uses symbols from the namespace it is defined in as well as symbols from the namespace where it is used.

 `(+ ~'x x)
 => (clojure.core/+ x user/x)
 `(+ ~x x)
 => (clojure.core/+ 3 user/x)

Finally, you can unquote a whole collection of quoted things splicing.

 `(+ ~@`(x x))
 => (clojure.core/+ user/x user/x)

See both xes could have been passed as a list of namespace-qualified symbols and would have been spliced into another list. You can not use ~ or ~@ outside of a backtick-quoted collection.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...