varbinding=> symbol init-expr
Executes the exprs in a context in which the symbols are bound to
vars with per-thread bindings to the init-exprs. The symbols refer
to the var objects themselves, and must be accessed with var-get and
var-set
;; with-local-vars allows you to write more imperative-style code, for cases
;; where you really want to. factorial isn't a case where it helps, but
;; it is short and familiar. Note that (var-get acc) can be abbreviated
;; as @acc
user=> (defn factorial [x]
(with-local-vars [acc 1, cnt x]
(while (> @cnt 0)
(var-set acc (* @acc @cnt))
(var-set cnt (dec @cnt)))
@acc))
#'user/factorial
user=> (factorial 7)
5040
(defmacro with-local-vars
"varbinding=> symbol init-expr
Executes the exprs in a context in which the symbols are bound to
vars with per-thread bindings to the init-exprs. The symbols refer
to the var objects themselves, and must be accessed with var-get and
var-set"
{:added "1.0"}
[name-vals-vec & body]
(assert-args with-local-vars
(vector? name-vals-vec) "a vector for its binding"
(even? (count name-vals-vec)) "an even number of forms in binding vector")
`(let [~@(interleave (take-nth 2 name-vals-vec)
(repeat '(. clojure.lang.Var (create))))]
(. clojure.lang.Var (pushThreadBindings (hash-map ~@name-vals-vec)))
(try
~@body
(finally (. clojure.lang.Var (popThreadBindings))))))
Comments top
No comments for with-local-vars. Log in to add a comment.