It's not totally true, either; there are other ways to do state in Clojure. But none of them simply let the programmer, you know, change the state of a variable.
What I was looking for can be done with atoms, and is made more like traditional lisp mutation by defining a "st!" (or maybe "zet!" is a better name).
(defn st! [atm v]
(swap! atm (fn [_] v)))
Now making ordinary lisp clojures is reasonable: (def fns
(let [c (atom 0)]
{:add (fn [x] (st! c (+ @c x)))
:mlt (fn [x] (st! c (* @c x)))}))
> ((get fns :add) 3)
3
> ((get fns :add) 3)
6
> ((get fns :mlt) -5)
-30
Though I sure could do without the calls to 'atom' and @. Referencing and dereferencing is for C programmers. Maybe using swap! directly is better after all. (def fns
(let [c (atom 0)]
{:add (fn [x] (swap! c #(+ % x)))
:mlt (fn [x] (swap! c #(* % x)))}))But what I really want it something that doesn't require dereferencing syntax:
(zet! c (* c x))I'm not sure wether this is good style. Probably not.
Edit: Bah. Fixed an error.
Sadly, as far as I know, you need to roll your own tree-reduce.
(swap! c (partial * 2))
on two separate threads, c will always end up 4x the original value.These limitations exist for a reason.
(swap! c * 2)