EDIT: Transducers are not safe in `fold` contexts either: (let [f (fn [i x] (println (str "i " i " " (Thread/currentThread))) (flush) x) r-map-indexed #(r/folder %2 (map-indexed %1))] (->> [6 7 8 9 10] (r-map-indexed f) (r/fold 1 (fn ([] (vector)) ([x] x) ([a b] (into a b))) conj)))
Produces: i 0 Thread[ForkJoinPool-1-worker-2,5,main] i 2 Thread[ForkJoinPool-1-worker-1,5,main] i 3 Thread[ForkJoinPool-1-worker-1,5,main] i 4 Thread[ForkJoinPool-1-worker-1,5,main] i 1 Thread[ForkJoinPool-1-worker-3,5,main] So you would have to be careful to create different `map-indexed` transducers for single-threaded and multi-threaded contexts. On Sunday, April 9, 2017 at 2:11:03 AM UTC-4, Alexander Gunnarson wrote: > > I was wondering the same thing, Jörg. This thread > <https://groups.google.com/forum/#!topic/clojure/VQj0E9TJWYY> talks about > it as well. I posted a note there which I will reproduce here for your > convenience: > > I think it's safe to assume that since `ArrayList` uses unsynchronized > mutability internally (a quick review of the GrepCode entry for > `ArrayList` confirms this > <http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/ArrayList.java>), > > then we can rest assured that a `volatile` box as opposed to a totally > unsynchronized mutable variable is unnecessary, even in the context of > `fold`. After all, `reduce` (and by extension, `transduce`) is only ever > going to be single-threaded unless the data structure in question > unexpectedly implements a multithreaded reduce, which should never happen > (and if it does, you likely have bigger problems). To be honest, I'm not > sure why `volatile` is used in transducers instead of e.g. an > `unsynchronized-mutable` box. There may be a good reason, but I'm not > seeing it immediately. I'd love to learn. > > On Friday, January 2, 2015 at 10:06:25 AM UTC-5, Jörg Winter wrote: >> >> So if I'd need that extra performance, say in a private library of >> transducers not intended to be shared with other Clojure developers, it is >> perfectly Ok to use a java.lang.Object instead of a volatile, right ? >> >> J >> >> 2015-01-02 15:59 GMT+01:00 Timothy Baldridge <tbald...@gmail.com>: >> >>> "As far as I understand, the step-function of a transducer is never(?) >>> accessed concurrently by more than 1 thread." >>> >>> It's actually "one thread at a time". And you're right, stuff like >>> Core.async may bounce a transducer between several different threads, but >>> only 1 thread "owns" it at a given time. >>> >>> Timothy >>> >>> On Fri, Jan 2, 2015 at 7:11 AM, Jörg Winter <jwin...@gmail.com> wrote: >>> >>>> Hi, >>>> >>>> As seen in this example of a stateful transducer... >>>> >>>> http://crossclj.info/ns/org.clojure/clojure/latest/clojure.core.html#_partition-by >>>> >>>> ... I am wondering what is the concrete motivation behind using >>>> 'volatile!' instead of say a simple (mutable) Java-Object wrapper ? >>>> In the partition-all example, an ArrayList is used for aggregating the >>>> 'temporary' results for the step-function, so this mutable state is not >>>> concerned with threading at all. >>>> Why then is there a threading-concern with pv (the volatile!) ? >>>> >>>> As far as I understand, the step-function of a transducer is never(?) >>>> accessed concurrently by more than 1 thread. >>>> >>>> Is volatile! necessary because transducers should be usable with >>>> core.async ? >>>> Or is it just an easy way to get a mutable object in Clojure ? >>>> >>>> >>>> Best, >>>> Joerg >>>> >>>> -- >>>> 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. >>>> >>> >>> >>> >>> -- >>> “One of the main causes of the fall of the Roman Empire was that–lacking >>> zero–they had no way to indicate successful termination of their C >>> programs.” >>> (Robert Firth) >>> >>> -- >>> 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 a topic in the >>> Google Groups "Clojure" group. >>> To unsubscribe from this topic, visit >>> https://groups.google.com/d/topic/clojure/CjxK7xEsOKQ/unsubscribe. >>> To unsubscribe from this group and all its topics, send an email to >>> clojure+u...@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.