Mutation is not a bad performance optimization, and is super useful when the 
algorithm in question just works better with it. 

--Ashton

Sent from my iPhone

> On Nov 10, 2014, at 11:11 AM, Jacob Goodson <submissionfight...@gmx.com> 
> wrote:
> 
> I like the map suggestion but there are still those times when mutation makes 
> for a cleaner hack(imo of course).
> 
>> On Monday, November 10, 2014 5:44:25 AM UTC-5, Thomas Heller wrote:
>> @Jacob: If you get too many arguments in a loop I found it best to use a map.
>> 
>> (loop [{:keys [a b c] :as state} a-map]
>>   (cond
>>    (and (= a 1) (= b 2))
>>    (recur (update state :a inc)) ;; 1.7+ only, otherwise use update-in
>>    ...))
>> 
>> Working with named arguments (vs. positional) is a lot more user-friendly 
>> since you don't have to repeat everything all the time.
>> 
>> HTH,
>> /thomas 
>> 
>>> On Monday, November 10, 2014 8:21:57 AM UTC+1, Jacob Goodson wrote:
>>> 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 clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> 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 clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
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 clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to