Timothy Pratley wrote:
>> I think if Clojure could do something like this (enforce a certain
>> kind of referentially transparent mutable local), that would be neat,
>>     
>
> It is possible to achieve this behavior explicitly:
> (defn create-add-2 []
>   (with-local-vars [x 1]
>     (do
>       (var-set x 2)
>       (let [z @x]
>         (fn [y] (+ y z))))))
> (def myc (create-add-2))
> user=> (myc 1)
> 3
> user=> (myc 2)
> 4
>
> A bit verbose, but also very clear about what is really mutable and
> what isn't.
>
>
>   
I am trying to understand the arguments here... so here is a summary. 
Please let me know if I missed something:
1) It is possible to get "internally" mutable state using 
with-local-vars and var-set. The problem here is that the "internal" 
state cannot be operated on my multiple threads concurrently. Thus 
functions defined this way will not automatically scale on multi-cores. 
One may have to be careful while wrapping such state in a closure and 
accessing it from multiple threads. However, they *will* allow to 
"naturally" write certain algorithms containing local mutation.
2) It is possible to get "internally" mutable state using clojure arrays 
and recur style re-binding. The problem here is that recur style 
rebinding may not be expressive enough to "naturally" encode certain 
algorithms.
3) It is possible to get "internally" mutable state using atoms (along 
with atom-set for better readability and convenience)... which seems 
like a nice suggestion. The problem here is the generic problem with 
atoms which should be used carefully under do-sync. Particularly, if an 
atom is indeed an "internal" state in a function's closure, and the 
closure itself is used in a transaction then we have problems due to 
transaction retries. So, we either use atoms assuming that the function 
closures *will* be retried in transactions which limits the situations 
in which atoms can be used or we make sure we document such function 
closures so that they are not used in do-sync (may be clojure can print 
a warning if it sees an atom being used inside a do-sync).

However, this problem occurs only if there is a closure. If the function 
is retried and the internal state is created afresh then do we still 
have a problem? Is this a valid way to handle "internal" mutable state 
which is not encapsulated in closures?

So can we conclude that atoms with atom-set can be freely used in 
functions which don't return closures around them and if we really need 
to do that, we should use refs instead (or use one of the first two 
options given in the beginning)?

Pinocchio


--~--~---------~--~----~------------~-------~--~----~
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
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to