3

考虑到有效的clojure形式:

    > (let [a 16 b 8] (/ a b))
2

我正在尝试手动构建它以便将其输入到eval呼叫中。我之前被repl拒绝了:

> (list 'let '[ 'a '16 'b '8 '] '(/ a b) )
RuntimeException Unmatched delimiter: ]  clojure.lang.Util.runtimeException (Util.java:156)
(/ a b)
RuntimeException Unmatched delimiter: )  clojure.lang.Util.runtimeException (Util.java:156)

引用数组字符[]是不够的。实际上,以下表达式(删除 [ 和 ])是可以的:

> (list 'let  'a '16 'b '8  '(/ a b) )
(let a 16 b 8 (/ a b))

这种结构有什么问题?我该如何解决这个问题?是否有任何特殊形式来引用 [ 和 ] 字符?

4

3 回答 3

5

如果您尝试生成代码,那么我建议您使用 auto-gensyms 构建此表达式,如下所示:

`(let [a# 16 b# 8] (/ a# b#))

auto-gensyms (a#b#) 创建保证唯一的符号名称。这不是绝对必要的,但在更复杂的情况下,它可以帮助避免变量名被意外捕获(例如,通过不同级别的宏扩展)。

请注意在表达式开头使用语法引号 (`) 而不是正则引号 (')。当您生成代码时,这通常比常规引用更好,因为它会自动处理命名空间。

于 2012-09-17T04:47:05.377 回答
4

您可以引用整个向量:

(list 'let '[a 16 b 8] '(/ a b))
于 2012-09-16T22:23:53.963 回答
4

您也可以引用整个列表。

main=> (def bar '(let [a 16 b 8] (/ a b)))
#'main/bar
main=> bar
(let [a 16 b 8] (/ a b))
main=> (eval bar)
2

或者这样...

main=> (def bar (quote (let [a 16 b 8] (/ a b))))
#'main/bar
main=> bar
(let [a 16 b 8] (/ a b))
main=> (eval bar)
2
于 2012-09-16T23:04:28.090 回答