On Monday, November 3, 2014 10:44:19 PM UTC-6, Atamert Ölçgen wrote: > > Thanks Alex! > > Now that I took a second look at Daniel's code, it seems assoc! is used > like swap!, as if it would modify m in place. So I would expect, if it runs > without errors, result to be {:a 0}. >
Right, that is an incorrect usage - it will actually modify with changes though, but not in expected ways (this is independent of the change we're discussing - you can get the same behavior in a single thread modifying a transient without reusing the return). Given that transients are values (not reference types like ref or atom) I > can't think of a case where they can be modified concurrently. > You can, but not without going pretty far out of normal Clojure code. > > > On Tue, Nov 4, 2014 at 11:19 AM, Alex Miller <al...@puredanger.com > <javascript:>> wrote: > >> >> >> On Monday, November 3, 2014 9:00:10 PM UTC-6, Atamert Ölçgen wrote: >>> >>> >>> >>> On Mon, Nov 3, 2014 at 5:57 PM, Daniel Marjenburgh <dmarje...@gmail.com> >>> wrote: >>> >>>> Hi, >>>> >>>> I just want to address this issue (CLJ-1498 >>>> <http://dev.clojure.org/jira/browse/CLJ-1498>). It was accepted in >>>> 1.7-alpha2 and I haven't seen a lot of discussion around it, even though >>>> it's quite a big change. >>>> >>>> With this change the following code is possible: >>>> >>> >>> With persistents the result would be the same, every time. If this is >>> now valid Clojure, I didn't run it myself, we are sacrificing consistency. >>> I don't understand what we're getting in return. >>> >>> Even the simple example in the ticket (with one future) doesn't make a >>> lot of sense to me. >>> >>> Am I missing something obvious? >>> >> >> Transients always expect thread isolation. In the past this was locked to >> a single thread (the one that made the transient). That restriction now >> extends to being used by multiple threads, but isolation should still be >> maintained for proper use. >> >> What we are gaining is the ability to use transient collections in go >> blocks with core.async, where the thread being used is just one pool out of >> a thread. For example (just typing this not running it, so excuse any >> typos): >> >> (defn drain [ch coll] >> (let [t (transient []] >> (go-loop >> (if-some [v (<! ch)] >> (do (conj! t v) (recur)) >> (persistent! t))))) >> >> This doesn't necessarily work in core.async because each time the <! >> parks, it may be woken up with a different thread from the pool. The >> transient change allows this kind of code to succeed. >> >> >>> >>>> (let [m (transient {:a 0}) >>>> futs (for [n (range 100)] >>>> (future (assoc! m :a (inc (:a m)))))] >>>> (mapv deref futs) ; wait until futures are done >>>> (persistent! m)) >>>> >>>> >>>> The results will vary per run, where it used to throw >>>> an IllegalAccessError: "Transient used by non-owner thread". >>>> >>>> I understand the problems of not being able to have 1 go routine access >>>> a transient, even though it would be safe, but this solution feels like >>>> it's throwing out the baby with the bathwater. Basically, it's doing away >>>> with what the following block on clojure.org >>>> <http://clojure.org/transients> says: >>>> >>>> *Transients enforce thread isolation**.* Because each result of a >>>>> transient operation shares (mutable) structure with the previous, it >>>>> would >>>>> be very dangerous if more than one thread were to manipulate a transient >>>>> at >>>>> once. In order to prevent this, transients will detect any (read or >>>>> write) >>>>> use from a thread other than the one that created them and throw an >>>>> exception. >>>> >>>> >>>> >>>>> >>>>> This may not sound like a concurrency story, but single-thread >>>>> isolation is actually a very useful concurrency semantic. The whole point >>>>> of using transients is that doing so is safe, because their use is an >>>>> isolated implementation detail of otherwise functional code. Having that >>>>> be >>>>> enforced means that some things that would normally be very hard to make >>>>> safe with ordinary mutable data structures become easy. >>>> >>>> >>>> I don't have a good solution for dealing with transients and logical >>>> threads, but I would much prefer keeping the semantics of transients as >>>> they are and maybe pass an option to transient to disable owner checking. >>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com. >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>> >>> >>> >>> -- >>> Kind Regards, >>> Atamert Ölçgen >>> >>> -+- >>> --+ >>> +++ >>> >>> www.muhuk.com >>> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clo...@googlegroups.com >> <javascript:> >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+u...@googlegroups.com <javascript:> >> 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+u...@googlegroups.com <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > > > > -- > Kind Regards, > Atamert Ölçgen > > -+- > --+ > +++ > > www.muhuk.com > -- 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.