在Clojure中,我们可以使用非引号切片(
这是在重组语法时非常有用的宏功能。但是否有可能在宏之外且不使用
以下是使用
起初我认为
~@
)来展开列表。例如:(macroexpand `(+ ~@'(1 2 3)))
扩展为
(clojure.core/+ 1 2 3)
这是在重组语法时非常有用的宏功能。但是否有可能在宏之外且不使用
eval
的情况下使用解引用切片或熟悉的技术呢?以下是使用
eval
的解决方案。(eval `(+ ~@'(1 2 3))) ;-> 6
但我更愿意这样做
(+ ~@'(1 2 3))
不幸的是,这会抛出一个错误
IllegalStateException Attempting to call unbound fn: #'clojure.core/unquote-splicing clojure.lang.Var$Unbound.throwArity (Var.java:43)
起初我认为
apply
可以做到这一点,对于函数来说确实如此。(apply + '(1 2 3)) ; -> 6
然而,宏或特殊形式并非如此。这对于宏很明显,因为它在应用之前被扩展,必须是表单中的第一个元素。对于特殊形式来说并不是那么明显,但仍然有意义,因为它们不像函数一样是头等公民。例如,以下内容会抛出错误:
(apply do ['(println "hello") '(println "world")]) ;-> error
在运行时“应用”列表的唯一方法是使用非引用切片和eval
吗?