3

Clojureのletものはシーケンシャルで、スキームに対応しているようですlet*。clojure にはスキームのような非順次バインディング機構がありletますか?

4

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

bindingletバインディングの存在に依存するため、パラレルと同じ機能は提供されません。前述のよう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 に答える