Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a function local mutable variable in ClojureScript?

Consider the following hypothetical nonsensical ClojureScript function:

(defn tmp [] 
  (def p 0)
  (set! p (inc p))
  (set! p (inc p))
  (set! p (inc p)))

Repeatedly executing this function in a REPL results in

3
6
9
etc.

Is it possible to create a mutable variable which is local to the function, such that the output would have been

3
3
3
etc. 

in the case of repeated exection of (tmp)?

like image 720
nilo de roock Avatar asked Apr 25 '16 17:04

nilo de roock


1 Answers

let lets you assign variables limited to it's scope:

(defn tmp[]
  (let [p 0]
    ...))

Now, clojurescript makes use of immutable data. That means everything is basically a constant, and once you set a value of p, there is no changing it. There are two ways you can get around this:

Use more local variables

(defn tmp[]
  (let [a 0
        b (inc a)
        c (inc b)
        d (inc c)]
    ...))

Use an atom

Atoms are somewhat different from other data structures in clojurescript and allow control of their state. Basically, you can see them as a reference to your value.

When creating an atom, you pass the initial value as its argument. You can access an atoms value by adding @ in front of the variable, which is actually a macro for (deref my-var).

You can change the value of an atom using swap! and reset! functions. Find out more about them in the cljs cheatsheet.

(defn tmp[]
  (let [p (atom 0)]
    (reset! p (inc @p))
    (reset! p (inc @p))
    (reset! p (inc @p))))

Hope this helps.

like image 107
Kuba Birecki Avatar answered Nov 09 '22 10:11

Kuba Birecki