4

Clojure 1.2 を使用すると、このコードは機能します

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

しかし、次のコードは 3 行目で失敗します

(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

編集:なぜ引数なしで動作し、引数が1つで失敗するのかという問題について:

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 に答える