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