Clojureのlet
ものはシーケンシャルで、スキームに対応しているようですlet*
。clojure にはスキームのような非順次バインディング機構がありlet
ますか?
3 に答える
4
binding
マクロはシーケンシャルではなくパラレルだと思います。
参照: http://clojuredocs.org/clojure_core/clojure.core/binding
于 2012-08-07T19:59:02.823 に答える
2
letfn は、人々が相互に再帰的なローカル関数を記述できるようにするために存在する、関数の並列バインディング形式です。ピンチで使用できますが、求めるほど一般的ではありません。
user> (letfn [(a [] 4)
(b [] c)
(c [] a)]
(a))
4
変数内のものに値を代入し、動的なスコープが必要な限り、バインディングを使用できます
user> (def ^:dynamic x 4)
#'user/x
user> (defn foo [] x)
#'user/foo
user> (binding [x 8] (+ x (foo)))
16 ; the value of x that gets called by foo is modified by the caller
; yielding 16 instead of 12
user> (binding [x 8 a 7] (+ x (foo)))
; Evaluation aborted.
Unable to resolve var: a in this context
並列バインディングを使用しようとすると、動的スコープにより、Scheme での let* とは異なる結果が得られます。
user> (def ^:dynamic a 2)
#'user/a
user> (binding [x 8 a 7] (+ x a))
15
user> (binding [x 8 a (+ x 2)] (+ x a))
14 ; this would be 18 if the binding of x to 8 had been used
; instead the root value of 4 was used.
一般的には、順次バインドするlet
か、必要に応じてネストされた s を使用するのが最も一般的です。
于 2012-08-07T20:27:00.480 に答える
0
binding
let
バインディングの存在に依存するため、パラレルと同じ機能は提供されません。前述のようletfn
に、値を関数でラップすることを気にしない限り機能します。もう 1 つの解決策は、マクロを使用して並列 let を記述することです。
(defmacro letp
[bindings & exprs]
(let [bindings (partition 2 bindings)
vars (->> bindings (map first) vec)
values (->> bindings (map second))]
`((fn ~vars ~@exprs)
~@values)))
したがって、次のことが成り立ちます。
(def a 7)
(letp [a 5 b a] b)
;;=> 7
于 2012-08-08T01:46:27.007 に答える