4

使用 Clojure 1.2,此代码有效

(defn A [] (fn [a] (+ a 2)))
(println ((A) 0))
(println (eval (list (A) 0)))

但以下代码在第三行失败

(defn A [b] (fn [a] (+ a b)))
(println ((A 3) 0))
(println (eval (list (A 3) 0)))

为什么?

4

1 回答 1

3

调用(list (A 3))返回列表中的函数:

user> (list (A 3) 0)
(#<user$A$fn__2934 user$A$fn__2934@2f09b4cb> 0)

eval期望在列表中获得一个符号,并且它正在获得它自己的功能。如果您引用电话,(A 3)那么您将获得您寻求的结果

user> (println (eval (list '(A 3) 0)))
3
nil

此代码的一部分在调用之前被评估eval,然后eval正在评估其余部分。更常见的是将 eval 用于带有术语的引用形式或选择性地不引用 ( ~)。

user> (eval '((A 3) 0))
3

或者

user> (def my-number 3)
#'user/my-number
user> (eval `((A ~my-number) 0))
3

编辑:关于为什么它使用零参数而失败的问题:

如果您不将它们存储在 vars 中(即使用 defn 定义它们)而是手动内联它们,那么这两种形式似乎都可以工作:

user> (def A (fn [b] (fn [a] (+ a b))))
#'user/A
user> (eval (list (A 3) 0))
; Evaluation aborted.
user> (eval (list (fn [b] (fn [a] (+ a b)) 3) 0))
3
于 2012-07-27T23:22:19.713 回答