看起来 clojurelet
是顺序的,并且对应于一个 scheme let*
。clojure 是否具有像 scheme's 这样的非顺序绑定机制let
?
问问题
184 次
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
只要您将值分配给 vars 中的事物并想要动态范围,就可以使用绑定
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
如果您尝试使用并行绑定,则动态作用域将给出与方案中的 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
,只要您不介意将值包装在函数中,它就会起作用。另一种解决方案是使用宏编写并行 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 回答