Sometimes, when writing code that loops with a good bit of branching, it
can be quite annoying to stay immutable.
(loop [way 1
too 2
many 3
args 4
makes 5
things 6
annoying 7]
(cond (and (= way 3) (= too 4)) (recur (inc way).... you get the point.
Imagine about 14 different conditions under cond and this thing starts
looking like crap. I got around this with macros and pattern matching,
however, I do not think that this happens too often for many clojurians.
On Saturday, November 8, 2014 11:49:42 PM UTC-5, Fluid Dynamics wrote:
>
> I wonder if the OP is aware that you can rebind the same name multiple
> times in a let. For instance
>
> (let [x something
> y otherthing
> x (if (pred? x y) x (some-func x y))
> x (further (complex (calculations x)))
> ...]
> (do-something-with x))
>
> No actual mutability, but most of the times that suffices for whatever you
> might use a mutable local for in another language.
>
> Then there's loop/recur. I'd consider let rebinding and loop/recur long
> before resorting to any sort of mutable. The most significant pain point in
> my experience has been wanting to "smuggle" a side calculation out of some
> closure that has to return something else. The most recent case I ran into
> like that involved (swap! some-atom conj thingy) where the atom held a
> vector, I also wanted to know the new length of the vector, I didn't want
> any race conditions (following up with a (count @some-atom) allowed the
> possibility of the vector changing again in between the swap and the deref,
> but I wanted to know the position of the item just conjed on), and
> dosync/ref seemed like overkill (only the one isolated mutable). I *could*
> have done something like
>
> (let [c (int-array 1)]
> (swap! some-atom (fn [x] (let [x (conj x thingy)] (aset c 0 (count x))
> x)))
> (let [c (aget c 0)]
> ; work with c
> ...))
>
> but it was unnecessary to use this kluge, for swap! returns not the atom
> itself but the new value that was returned by the passed-in function. So
> all I actually needed was
>
> (let [c (count (swap! some-atom conj thingy))]
> ...)
>
> with no mutability besides the atom itself (and in particular no local
> mutability). I've since needed swap!'s return value on another occasion,
> when it was a map, resulting in (get-in (swap! m update-in [k1 k2] f arg1
> arg2) [k1 k2]) to both update the map and have the exact value for the
> sub-key that was updated, as of that update. With maps, it may also be
> possible to store some extra information in the map with a
> ::module-local-keyword without this interfering with anything else, which
> can be pulled out of swap!'s return value, and with several kinds of
> objects you can smuggle extra information out of a closure by adding a
> ::module-local-keyword to the object's *metadata* (in particular, this
> won't perturb the equality semantics of the object, as well as working with
> vectors and several other non-map-like things as well as with records and
> maps. And if you're wanting to return extra information out of an ordinary
> function or a loop where you control how the return value is interpreted,
> you can bind and destructure the return value after making that a short
> vector or a map with several thingys in it.
>
> Lately I hardly ever find myself feeling the need for any kind of local
> mutables, and only small amounts of global state (often nothing, or just
> one atom wrapping a map handled with nesting, update-in, assoc-in, and
> get-in, though refs and dosync will put in an appearance if a high degree
> of concurrency is required).
>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.