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.

Reply via email to