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)))
なんで?
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)))
なんで?
呼び出す(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