with-local-vars

added
1.0

ns
clojure.core

type
macro

(with-local-vars name-vals-vec & body)

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

            
                (with-local-vars [a-local-var-variable "value"]
                 ;; If you use the symbol by itself, you get the Var back
                 (println a-local-var-variable)
                 ;; So when using local var variables, you must explicitly
                 ;; get the value inside the Var
                 (println (var-get a-local-var-variable))
                 ;; You can also get the value of a Var by using deref
                 (println (deref a-local-var-variable))
                 ;; Or the @ reader macro
                 (println @a-local-var-variable))
            
                ;; with-local-vars allows you to write more imperative-style code, for cases
;; where you really want to. This example demonstrate how to change variable value
;; like in for-loop. There used doseq instead of for, because for is a macros
;; that generates lazy sequence that will be realized out of ranges
;; with-local-vars block 
(with-local-vars [n 0]  
                 (doseq [x (range 3)]
                        (do (var-set n (inc (var-get n)))
                            (println (var-get n)))))
;   1
;   2
;   3
;=> nil