mik*_*era 5 macros clojure quoting
在Clojure中,您可以取消引用拼接值列表以生成代码,例如
(def extra-values [1 2 3 4])
`(+ 100 200 ~@extra-values)
=> (clojure.core/+ 100 200 1 2 3 4)
Run Code Online (Sandbox Code Playgroud)
似乎合乎逻辑的是,相同的方法应该在不带引号的上下文中起作用,例如
(def extra-values [1 2 3 4])
(+ 1000 ~@extra-values)
=> [an error, but one could argue that the answer should be 1010??]
Run Code Online (Sandbox Code Playgroud)
有什么深刻的技术/哲学原因,为什么这不起作用?
ama*_*loy 13
一个简单的原因是
`(+ 100 200 ~@extra-values)
Run Code Online (Sandbox Code Playgroud)
定义不明确:它是否扩展到
(+ 100 200 1 2 3 4)
Run Code Online (Sandbox Code Playgroud)
或者
(+ 100 200 ~@extra-values)
Run Code Online (Sandbox Code Playgroud)
?如果~@构造在该上下文中是合法的,则两者都是有效的解释.
它还会导致宏观系统出现严重问题.考虑
(defmacro foo [x & args]
`(list ~x ~(count args)))
(let [data '(1 2 3)]
(foo "three" ~@data))
Run Code Online (Sandbox Code Playgroud)
怎么foo知道它传递的是什么?它当然不能在编译时扩展它,所以现在unquote-splicing只在一些非引用的上下文中有效.
总的来说,它只是混淆了语言,以适应对核心概念的不理解 - 如果你真的想要取消引用拼接来构建复杂的参数列表,你可以轻松地使用apply类似的东西
(apply + `(100 ~@extra-values 200))
Run Code Online (Sandbox Code Playgroud)