4 ms·
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 variabl
by herdrick 16y ago
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.
- lukev 16y agoSure they do. Thread-local vars behave pretty much like regular variables. Atoms also get you uncoordinated state.
- herdrick 16y agoOK, thanks for the tip about atoms. I hadn't dug into the var/atom/ref/agent docs. I should have before commenting. 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)))}))
- prospero 16y agoThe function you're looking for is 'reset!'
- herdrick 16y agoAh, thank you. But what I really want it something that doesn't require dereferencing syntax: (zet! c (* c x))
- die_sekte 16y agoThis would work: http://gist.github.com/536715 http://gist.github.com/536715 I'm not sure wether this is good style. Probably not. Edit: Bah. Fixed an error.
- herdrick 16y ago'replace-in-form' is a tree-replace, which in Clojure is done with clojure.walk/postwalk-replace. The clojure.walk package is basically tree-map stuff. Sadly, as far as I know, you need to roll your own tree-reduce.
- die_sekte 16y agoThanks for that. I did look at clojure.walk, I just didn't look close enough.
- prospero 16y agoIf you evaluate your expression on two different threads, the value of c is non-deterministic. On the other hand, if you call (swap! c (partial * 2)) on two separate threads, c will always end up 4x the original value. These limitations exist for a reason.
- weavejester 16y agoIt's worth noting you could also write: (swap! c * 2)
- prospero 16y agoYeah, I just thought that looked close enough to infix notation to be confusing.
- herdrick 16y agoAlso, where did you find reset! ? It's not on the atoms page in the main documents.