Re: [ANN] Clojure 1.7.0-alpha2
On Wednesday, September 10, 2014 10:53:27 PM UTC+2, Alex Miller wrote: On Wednesday, September 10, 2014 11:05:36 AM UTC-5, puzzler wrote: When I explain to new Clojurists what the ! means, I explain that it calls attention to a mutation function that is unsafe to call inside a transaction. Many programmers coming from Scheme are used to thinking of ! as meaning *anything* involving mutation, but that's not the case in the Clojure. This more subtle distinction (that it needs to be unsafe in a transaction) clarifies why swap! has an exclamation point, but ref-set does not, even though both involve mutation. I do not think there is a hard definition of what ! means as a suffix. Use the bang! only for things not safe in an STM transaction. -- http://dev.clojure.org/display/community/Library+Coding+Standards AFAICT, that definition was consistently used in the past in core and I used it in workshops, too. And yes, the same page says Rules are made to be broken. Know the standards, but do not treat them as absolutes. Just wanted to add this to the discussion stefan -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
I can understand why something like a clojure.lang.Volatile can be useful for some optimizations in the functions of standard library, but do they really need to become part of the public core API? Clojure is such a nice language because of the way state is handled at a higher level. Whenever I use a library, I _know_ the data I'm given is immutable. And whenever I'm given a state container such as an atom, I _know_ exactly how I can use it and, more importantly, share it. With a volatile container, I don't[1]. It's just a plain-old mutable variable, something Clojure rightfully moved away from. Sure, an API that returns a volatile should be considered a very bad practice, but I think this is still going to happen[2]. Especially by those coming to Clojure in the future with a OO background. Understanding and maintaining someone else's code might become harder as well. Having the volatile function as part of the public core API sends the wrong message in my opinion. Could you, Cognitect, consider making the volatile related functions private, or move them to their own namespace, in order to keep Clojure more true to its nature? [1] This is also a reason why I think the idea of overloading swap! and reset! not desirable. [2] Transients don't have this problem, as they cannot escape their score. -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
FYI transients no longer enforce thread locality, and you may now call them from any thread [1]. More options for handling mutable state is not a bad thing (as Clojure is a practical language), though more discipline will be needed. Jozef [1] CLJ-1498 On Thu, Sep 11, 2014 at 9:41 AM, Arnout Roemers goo...@company.romeinszoon.nl wrote: I can understand why something like a clojure.lang.Volatile can be useful for some optimizations in the functions of standard library, but do they really need to become part of the public core API? Clojure is such a nice language because of the way state is handled at a higher level. Whenever I use a library, I _know_ the data I'm given is immutable. And whenever I'm given a state container such as an atom, I _know_ exactly how I can use it and, more importantly, share it. With a volatile container, I don't[1]. It's just a plain-old mutable variable, something Clojure rightfully moved away from. Sure, an API that returns a volatile should be considered a very bad practice, but I think this is still going to happen[2]. Especially by those coming to Clojure in the future with a OO background. Understanding and maintaining someone else's code might become harder as well. Having the volatile function as part of the public core API sends the wrong message in my opinion. Could you, Cognitect, consider making the volatile related functions private, or move them to their own namespace, in order to keep Clojure more true to its nature? [1] This is also a reason why I think the idea of overloading swap! and reset! not desirable. [2] Transients don't have this problem, as they cannot escape their score. -- 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. -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
Using my timings macro: https://gist.github.com/fsodomka/5890711 I am getting that: - creation derefing is 60% faster - swapping is 25% faster - resetting is about the same ;; volatile vs. atom ;; (report (timings 1e7 (deref (volatile! 42)) (deref (atom 42 ; | :expr | :time | :ratio | :perc | ; |+---++---| ; | (deref (volatile! 42)) | 30.688238 |1.0 | 39.81 | ; | (deref (atom 42)) | 77.081141 | 2.51 | 100.0 | (report (let [v (volatile! 42) a (atom 42)] (timings 1e7 (vswap! v inc) (swap! a inc ; | :expr | :time | :ratio | :perc | ; |+++---| ; | (vswap! v inc) | 136.052946 |1.0 | 75.08 | ; | (swap! a inc) | 181.218748 | 1.33 | 100.0 | (report (let [v (volatile! 42) a (atom 42)] (timings 1e7 (vreset! v 10) (reset! a 10 ; | :expr | :time | :ratio | :perc | ; |+---++---| ; | (reset! a 10) | 98.755318 |1.0 | 96.69 | ; | (vreset! v 10) | 102.13944 | 1.03 | 100.0 | On Thursday, September 11, 2014 6:18:08 AM UTC+2, puzzler wrote: I'm curious: how much faster are volatiles than atoms? -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
And just creation is about 3x faster: (report (timings 1e7 (do (volatile! 42) nil) (do (atom 42) nil))) ; | :expr | :time | :ratio | :perc | ; |-+---++---| ; | (do (volatile! 42) nil) | 22.849963 |1.0 | 31.63 | ; | (do (atom 42) nil) | 72.237439 | 3.16 | 100.0 | On Thursday, September 11, 2014 11:06:44 AM UTC+2, Frantisek Sodomka wrote: Using my timings macro: https://gist.github.com/fsodomka/5890711 I am getting that: - creation derefing is 60% faster - swapping is 25% faster - resetting is about the same ;; volatile vs. atom ;; (report (timings 1e7 (deref (volatile! 42)) (deref (atom 42 ; | :expr | :time | :ratio | :perc | ; |+---++---| ; | (deref (volatile! 42)) | 30.688238 |1.0 | 39.81 | ; | (deref (atom 42)) | 77.081141 | 2.51 | 100.0 | (report (let [v (volatile! 42) a (atom 42)] (timings 1e7 (vswap! v inc) (swap! a inc ; | :expr | :time | :ratio | :perc | ; |+++---| ; | (vswap! v inc) | 136.052946 |1.0 | 75.08 | ; | (swap! a inc) | 181.218748 | 1.33 | 100.0 | (report (let [v (volatile! 42) a (atom 42)] (timings 1e7 (vreset! v 10) (reset! a 10 ; | :expr | :time | :ratio | :perc | ; |+---++---| ; | (reset! a 10) | 98.755318 |1.0 | 96.69 | ; | (vreset! v 10) | 102.13944 | 1.03 | 100.0 | On Thursday, September 11, 2014 6:18:08 AM UTC+2, puzzler wrote: I'm curious: how much faster are volatiles than atoms? -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
The volatile construct seems very useful in some particular cases! I have been missing ugly-mutable variables for things such as certain types of heaps/queues or write-intensive, slightly probabilistic stuff where one missed write doesn't matter that much. For people who don't have a Java background, I just want to point the very useful package java.util.concurrent.atomic, in which one can find gems such as AtomicLong, which is almost unbeatable as a counter. An example in which an AtomicLong is about three times quicker than an atom: https://gist.github.com/claj/6711556#file-countertest-clj Javadoc for AtomicLong: http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicLong.html In the sake of completeness, Linus 2014-09-11 11:06 GMT+02:00 Frantisek Sodomka fsodo...@gmail.com: Using my timings macro: https://gist.github.com/fsodomka/5890711 I am getting that: - creation derefing is 60% faster - swapping is 25% faster - resetting is about the same ;; volatile vs. atom ;; (report (timings 1e7 (deref (volatile! 42)) (deref (atom 42 ; | :expr | :time | :ratio | :perc | ; |+---++---| ; | (deref (volatile! 42)) | 30.688238 |1.0 | 39.81 | ; | (deref (atom 42)) | 77.081141 | 2.51 | 100.0 | (report (let [v (volatile! 42) a (atom 42)] (timings 1e7 (vswap! v inc) (swap! a inc ; | :expr | :time | :ratio | :perc | ; |+++---| ; | (vswap! v inc) | 136.052946 |1.0 | 75.08 | ; | (swap! a inc) | 181.218748 | 1.33 | 100.0 | (report (let [v (volatile! 42) a (atom 42)] (timings 1e7 (vreset! v 10) (reset! a 10 ; | :expr | :time | :ratio | :perc | ; |+---++---| ; | (reset! a 10) | 98.755318 |1.0 | 96.69 | ; | (vreset! v 10) | 102.13944 | 1.03 | 100.0 | On Thursday, September 11, 2014 6:18:08 AM UTC+2, puzzler wrote: I'm curious: how much faster are volatiles than atoms? -- 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. -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
May be the LongAdder in Java8 can beat AtomicLong :D http://blog.palominolabs.com/2014/02/10/java-8-performance-improvements-longadder-vs-atomiclong/ 2014-09-11 17:30 GMT+08:00 Linus Ericsson oscarlinuserics...@gmail.com: The volatile construct seems very useful in some particular cases! I have been missing ugly-mutable variables for things such as certain types of heaps/queues or write-intensive, slightly probabilistic stuff where one missed write doesn't matter that much. For people who don't have a Java background, I just want to point the very useful package java.util.concurrent.atomic, in which one can find gems such as AtomicLong, which is almost unbeatable as a counter. An example in which an AtomicLong is about three times quicker than an atom: https://gist.github.com/claj/6711556#file-countertest-clj Javadoc for AtomicLong: http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicLong.html In the sake of completeness, Linus 2014-09-11 11:06 GMT+02:00 Frantisek Sodomka fsodo...@gmail.com: Using my timings macro: https://gist.github.com/fsodomka/5890711 I am getting that: - creation derefing is 60% faster - swapping is 25% faster - resetting is about the same ;; volatile vs. atom ;; (report (timings 1e7 (deref (volatile! 42)) (deref (atom 42 ; | :expr | :time | :ratio | :perc | ; |+---++---| ; | (deref (volatile! 42)) | 30.688238 |1.0 | 39.81 | ; | (deref (atom 42)) | 77.081141 | 2.51 | 100.0 | (report (let [v (volatile! 42) a (atom 42)] (timings 1e7 (vswap! v inc) (swap! a inc ; | :expr | :time | :ratio | :perc | ; |+++---| ; | (vswap! v inc) | 136.052946 |1.0 | 75.08 | ; | (swap! a inc) | 181.218748 | 1.33 | 100.0 | (report (let [v (volatile! 42) a (atom 42)] (timings 1e7 (vreset! v 10) (reset! a 10 ; | :expr | :time | :ratio | :perc | ; |+---++---| ; | (reset! a 10) | 98.755318 |1.0 | 96.69 | ; | (vreset! v 10) | 102.13944 | 1.03 | 100.0 | On Thursday, September 11, 2014 6:18:08 AM UTC+2, puzzler wrote: I'm curious: how much faster are volatiles than atoms? -- 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. -- 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. -- 庄晓丹 Email:killme2...@gmail.com xzhu...@avos.com Site: http://fnil.net Twitter: @killme2008 -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
On Thursday, September 11, 2014 2:41:44 AM UTC-5, Arnout Roemers wrote: I can understand why something like a clojure.lang.Volatile can be useful for some optimizations in the functions of standard library, but do they really need to become part of the public core API? From my own perspective (not talking for anyone else here), Clojure is a language that *empowers* you by giving you powerful, composable, expressive tools to solve hard problems. There are guidelines for use but pushing past those guidelines is ok (and expected) as your skills increases or as problems demand it. In this case my general guideline would be: don't use volatiles. Just like learning a musical instrument, learning how best to use the language (and when to break the rules) takes time and practice. -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
Oops, I skipped the volatile keyword while reading the code snippet. Sorry :) Luc P. No, it means exactly the same thing as volatile in Java (and is implemented in the Volatile Java class which holds a single volatile field). Basically a volatile box since a field must exist inside a class. The semantics are the same as Java - writes are guaranteed to be seen by subsequent reads on any thread (that property is not guaranteed by a non-volatile field). vswap! on a volatile is syntactically similar to swap! on an atom but without the atomicity guarantees. That is, vswap! consists of a read followed by a write but this is non-transactional so another thread could change the value in between. In other words: don't use this unless you can enforce thread isolation or safety through other means. Thus, volatiles are dangerous *by default*, unlike every other stateful thing in Clojure. Some stateful transducers use volatiles for performance and provide thread isolation via how they are constructed and used. On Tuesday, September 9, 2014 12:06:36 PM UTC-5, Luc wrote: The keyword has different meaning depending on the language and context. Most of the time to prevent optimizations by the compiler to insure write ordering and some consistent view (Java use). Not here. It's meant to warn that nothing is guaranteed, no synchronization, no consistent view. It should be kept local (no leak outside of a narrow scope) and certainly not shared by multiple threads. Luc P. Excuse my ignorance but does volatile! have anything to do with Java's volatile keyword? Is there any relation at all? I'm not suggesting a name change, but it can be confusing coming from that angle. Maybe a blurb in the doc string? -- 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. -- Luc Prefontainelprefo...@softaddicts.ca javascript: sent by ibisMail! -- 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. -- Softaddictslprefonta...@softaddicts.ca sent by ibisMail from my ipad! -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
I thereby promise to not use my mobile phone ever again to access github :) Luc P. Oops, I skipped the volatile keyword while reading the code snippet. Sorry :) Luc P. No, it means exactly the same thing as volatile in Java (and is implemented in the Volatile Java class which holds a single volatile field). Basically a volatile box since a field must exist inside a class. The semantics are the same as Java - writes are guaranteed to be seen by subsequent reads on any thread (that property is not guaranteed by a non-volatile field). vswap! on a volatile is syntactically similar to swap! on an atom but without the atomicity guarantees. That is, vswap! consists of a read followed by a write but this is non-transactional so another thread could change the value in between. In other words: don't use this unless you can enforce thread isolation or safety through other means. Thus, volatiles are dangerous *by default*, unlike every other stateful thing in Clojure. Some stateful transducers use volatiles for performance and provide thread isolation via how they are constructed and used. On Tuesday, September 9, 2014 12:06:36 PM UTC-5, Luc wrote: The keyword has different meaning depending on the language and context. Most of the time to prevent optimizations by the compiler to insure write ordering and some consistent view (Java use). Not here. It's meant to warn that nothing is guaranteed, no synchronization, no consistent view. It should be kept local (no leak outside of a narrow scope) and certainly not shared by multiple threads. Luc P. Excuse my ignorance but does volatile! have anything to do with Java's volatile keyword? Is there any relation at all? I'm not suggesting a name change, but it can be confusing coming from that angle. Maybe a blurb in the doc string? -- 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. -- Luc Prefontainelprefo...@softaddicts.ca javascript: sent by ibisMail! -- 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. -- Softaddictslprefonta...@softaddicts.ca sent by ibisMail from my ipad! -- 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. -- Softaddictslprefonta...@softaddicts.ca sent by ibisMail from my ipad! -- 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
Re: [ANN] Clojure 1.7.0-alpha2
So to summarize, Clojure's volatile provides synchronization across threads but does not provide atomaticity with vswap!. So, as a follow up question, then why would the creation of a volatile be dangerous but creating an atom isn't? (Hence the exclamation point in the name volatile!) -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
When I say synchronization, I specifically mean writes are guaranteed to be seen by subsequent reads on any thread* *as Alex said. On Wednesday, September 10, 2014 9:37:09 AM UTC-4, Brent Millare wrote: So to summarize, Clojure's volatile provides synchronization across threads but does not provide atomaticity with vswap!. So, as a follow up question, then why would the creation of a volatile be dangerous but creating an atom isn't? (Hence the exclamation point in the name volatile!) -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
Usually that's called visibility. Atoms are *not* subject to race conditions if swap! is called from multiple threads (the state of the atom will not change while the update function is being applied). The atom is thus safe to be used from multiple threads. Volatiles *are* subject to race conditions with vswap! is called from multiple threads (the state of the volatile may change while the update function is being applied). The volatile is thus dangerous and safety is derived from how it's used. On Wednesday, September 10, 2014 8:44:27 AM UTC-5, Brent Millare wrote: When I say synchronization, I specifically mean writes are guaranteed to be seen by subsequent reads on any thread* *as Alex said. On Wednesday, September 10, 2014 9:37:09 AM UTC-4, Brent Millare wrote: So to summarize, Clojure's volatile provides synchronization across threads but does not provide atomaticity with vswap!. So, as a follow up question, then why would the creation of a volatile be dangerous but creating an atom isn't? (Hence the exclamation point in the name volatile!) -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
As an example, if I have: (def a (atom 5)) and execute these from different threads: T1: (swap! a * 2) T2: (swap! a + 2) it depends on timing which update runs first so you can get either 12 (T1 then T2) or 14 (T2 then T1). But it must be one of those results. With a volatile, the reads and writes can interleave in a variety of ways (I think this is all of them as the JMM will guarantee that the read happens-before the write for each T): T1 read, T1 write, T2 read, T2 write: v = 12 T1 read, T2 read, T1 write, T2 write: v = 7 (T1 write is effectively lost) T1 read, T2 read, T2 write, T1 write: v = 10 (T2 write is effectively lost) T2 read, T2 write, T1 read, T1 write: v = 14 T2 read, T1 read, T2 write, T1 write: v = 10 (T2 write is effectively lost) T2 read, T1 read, T1 write, T2 write: v = 7 (T1 write is effectively lost) Non-atomic updates are fine if you have thread isolation though, as there is no chance for interleaving as above. The atomicity you get from atoms must be provided as a consequence of program construction in that case. There are a very small set of cases where non-atomic multi-threaded updates as above are actually valid. [The racy single-check idiom used for hash caching is one - that's a special case where the update function and initial value are identical so threads race to produce the *same* value, and all interleavings produce the same result. This technique used in several places in Clojure for hash caching.] Also note that the default in Java (non-volatile, non-synchronized fields) is even worse than this - they provide neither visibility nor atomicity, so different threads may not even seen writes by other threads at all (not to mention things like long-tearing). On Wednesday, September 10, 2014 9:19:33 AM UTC-5, Alex Miller wrote: Usually that's called visibility. Atoms are *not* subject to race conditions if swap! is called from multiple threads (the state of the atom will not change while the update function is being applied). The atom is thus safe to be used from multiple threads. Volatiles *are* subject to race conditions with vswap! is called from multiple threads (the state of the volatile may change while the update function is being applied). The volatile is thus dangerous and safety is derived from how it's used. On Wednesday, September 10, 2014 8:44:27 AM UTC-5, Brent Millare wrote: When I say synchronization, I specifically mean writes are guaranteed to be seen by subsequent reads on any thread* *as Alex said. On Wednesday, September 10, 2014 9:37:09 AM UTC-4, Brent Millare wrote: So to summarize, Clojure's volatile provides synchronization across threads but does not provide atomaticity with vswap!. So, as a follow up question, then why would the creation of a volatile be dangerous but creating an atom isn't? (Hence the exclamation point in the name volatile!) -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
When I explain to new Clojurists what the ! means, I explain that it calls attention to a mutation function that is unsafe to call inside a transaction. Many programmers coming from Scheme are used to thinking of ! as meaning *anything* involving mutation, but that's not the case in the Clojure. This more subtle distinction (that it needs to be unsafe in a transaction) clarifies why swap! has an exclamation point, but ref-set does not, even though both involve mutation. Assuming my description of Clojure's use of ! is correct (and if I'm wrong and am not thinking of some important counterexample, please let me know), then it doesn't really make sense for volatile to be called volatile!. Yes, volatiles are less safe than atoms, but the creation of the volatile itself is perfectly fine to occur in a transation. Only vswap! and vreset! require the exclamation point. I'd go one step further and question why we need new names vswap! and vreset!, when swap! and reset! are perfectly clear and sufficient. As Clojure has become increasingly interface and protocol-driven, it makes less and less sense to have a proliferation of function names for the same behavior on different underlying objects. vswap!, for example, is exactly the semantics you'd expect if you overloaded swap!, describing it as a function that can be applied to both atoms and volatiles, where volatiles are the more thread-unsafe, less atomic, alternative, because that's the nature of the underlying box. --Mark -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
That's also my explanation about the use of exclamation mark. IMHO, +1 for volatile, without !. Plínio On Wed, Sep 10, 2014 at 1:05 PM, Mark Engelberg mark.engelb...@gmail.com wrote: When I explain to new Clojurists what the ! means, I explain that it calls attention to a mutation function that is unsafe to call inside a transaction. Many programmers coming from Scheme are used to thinking of ! as meaning *anything* involving mutation, but that's not the case in the Clojure. This more subtle distinction (that it needs to be unsafe in a transaction) clarifies why swap! has an exclamation point, but ref-set does not, even though both involve mutation. Assuming my description of Clojure's use of ! is correct (and if I'm wrong and am not thinking of some important counterexample, please let me know), then it doesn't really make sense for volatile to be called volatile!. Yes, volatiles are less safe than atoms, but the creation of the volatile itself is perfectly fine to occur in a transation. Only vswap! and vreset! require the exclamation point. I'd go one step further and question why we need new names vswap! and vreset!, when swap! and reset! are perfectly clear and sufficient. As Clojure has become increasingly interface and protocol-driven, it makes less and less sense to have a proliferation of function names for the same behavior on different underlying objects. vswap!, for example, is exactly the semantics you'd expect if you overloaded swap!, describing it as a function that can be applied to both atoms and volatiles, where volatiles are the more thread-unsafe, less atomic, alternative, because that's the nature of the underlying box. --Mark -- 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. -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
I've also been explaining them the same way as Mark. On 10 September 2014 17:28, Plínio Balduino pbaldu...@gmail.com wrote: That's also my explanation about the use of exclamation mark. IMHO, +1 for volatile, without !. Plínio On Wed, Sep 10, 2014 at 1:05 PM, Mark Engelberg mark.engelb...@gmail.com wrote: When I explain to new Clojurists what the ! means, I explain that it calls attention to a mutation function that is unsafe to call inside a transaction. Many programmers coming from Scheme are used to thinking of ! as meaning *anything* involving mutation, but that's not the case in the Clojure. This more subtle distinction (that it needs to be unsafe in a transaction) clarifies why swap! has an exclamation point, but ref-set does not, even though both involve mutation. Assuming my description of Clojure's use of ! is correct (and if I'm wrong and am not thinking of some important counterexample, please let me know), then it doesn't really make sense for volatile to be called volatile!. Yes, volatiles are less safe than atoms, but the creation of the volatile itself is perfectly fine to occur in a transation. Only vswap! and vreset! require the exclamation point. I'd go one step further and question why we need new names vswap! and vreset!, when swap! and reset! are perfectly clear and sufficient. As Clojure has become increasingly interface and protocol-driven, it makes less and less sense to have a proliferation of function names for the same behavior on different underlying objects. vswap!, for example, is exactly the semantics you'd expect if you overloaded swap!, describing it as a function that can be applied to both atoms and volatiles, where volatiles are the more thread-unsafe, less atomic, alternative, because that's the nature of the underlying box. --Mark -- 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. -- 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. -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
On Wednesday, September 10, 2014 11:05:36 AM UTC-5, puzzler wrote: When I explain to new Clojurists what the ! means, I explain that it calls attention to a mutation function that is unsafe to call inside a transaction. Many programmers coming from Scheme are used to thinking of ! as meaning *anything* involving mutation, but that's not the case in the Clojure. This more subtle distinction (that it needs to be unsafe in a transaction) clarifies why swap! has an exclamation point, but ref-set does not, even though both involve mutation. I do not think there is a hard definition of what ! means as a suffix. Assuming my description of Clojure's use of ! is correct (and if I'm wrong and am not thinking of some important counterexample, please let me know), then it doesn't really make sense for volatile to be called volatile!. Yes, volatiles are less safe than atoms, but the creation of the volatile itself is perfectly fine to occur in a transaction. Only vswap! and vreset! require the exclamation point. The name is not going to change, sorry. I'd go one step further and question why we need new names vswap! and vreset!, when swap! and reset! are perfectly clear and sufficient. As Clojure has become increasingly interface and protocol-driven, it makes less and less sense to have a proliferation of function names for the same behavior on different underlying objects. vswap!, for example, is exactly the semantics you'd expect if you overloaded swap!, describing it as a function that can be applied to both atoms and volatiles, where volatiles are the more thread-unsafe, less atomic, alternative, because that's the nature of the underlying box. vswap! and vreset! do something similar in shape but different in meaning than swap! and reset! (they are non-atomic). As with all the stateful containers, the functions are specific to the container type (alter-var-root, alter, send, etc). --Mark -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
I understand usage of volatiles are dangerous via vswap! but what about creation? Again relating to what you said, 'I asked Rich and he said making a volatile is as dangerous as any ! op.' On Wednesday, September 10, 2014 10:19:33 AM UTC-4, Alex Miller wrote: Usually that's called visibility. Atoms are *not* subject to race conditions if swap! is called from multiple threads (the state of the atom will not change while the update function is being applied). The atom is thus safe to be used from multiple threads. Volatiles *are* subject to race conditions with vswap! is called from multiple threads (the state of the volatile may change while the update function is being applied). The volatile is thus dangerous and safety is derived from how it's used. On Wednesday, September 10, 2014 8:44:27 AM UTC-5, Brent Millare wrote: When I say synchronization, I specifically mean writes are guaranteed to be seen by subsequent reads on any thread* *as Alex said. On Wednesday, September 10, 2014 9:37:09 AM UTC-4, Brent Millare wrote: So to summarize, Clojure's volatile provides synchronization across threads but does not provide atomaticity with vswap!. So, as a follow up question, then why would the creation of a volatile be dangerous but creating an atom isn't? (Hence the exclamation point in the name volatile!) -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
Perhaps me means dangerous as in it shouldn't be done causually, and that it could become a problematic habit if formed. On Wed, Sep 10, 2014 at 8:55 PM, Brent Millare brent.mill...@gmail.com wrote: I understand usage of volatiles are dangerous via vswap! but what about creation? Again relating to what you said, 'I asked Rich and he said making a volatile is as dangerous as any ! op.' On Wednesday, September 10, 2014 10:19:33 AM UTC-4, Alex Miller wrote: Usually that's called visibility. Atoms are *not* subject to race conditions if swap! is called from multiple threads (the state of the atom will not change while the update function is being applied). The atom is thus safe to be used from multiple threads. Volatiles *are* subject to race conditions with vswap! is called from multiple threads (the state of the volatile may change while the update function is being applied). The volatile is thus dangerous and safety is derived from how it's used. On Wednesday, September 10, 2014 8:44:27 AM UTC-5, Brent Millare wrote: When I say synchronization, I specifically mean writes are guaranteed to be seen by subsequent reads on any thread* *as Alex said. On Wednesday, September 10, 2014 9:37:09 AM UTC-4, Brent Millare wrote: So to summarize, Clojure's volatile provides synchronization across threads but does not provide atomaticity with vswap!. So, as a follow up question, then why would the creation of a volatile be dangerous but creating an atom isn't? (Hence the exclamation point in the name volatile!) -- 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. -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
I'm curious: how much faster are volatiles than atoms? -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
Excuse my ignorance but does volatile! have anything to do with Java's volatile keyword? Is there any relation at all? I'm not suggesting a name change, but it can be confusing coming from that angle. Maybe a blurb in the doc string? -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
2014-09-09 18:54 GMT+02:00 Brent Millare brent.mill...@gmail.com: Excuse my ignorance but does volatile! have anything to do with Java's volatile keyword? Is there any relation at all? I'm not suggesting a name change, but it can be confusing coming from that angle. Maybe a blurb in the doc string? I figure it's named volatile, because it utilizes a volatile field to store the ref. Kind of like a stripped - down var. It also alludes to the consistency guarantees of volatile fields in the java memory model. See also ^:volatile-mutable vs ^:unsynchronized-mutable on deftype fields. -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
The keyword has different meaning depending on the language and context. Most of the time to prevent optimizations by the compiler to insure write ordering and some consistent view (Java use). Not here. It's meant to warn that nothing is guaranteed, no synchronization, no consistent view. It should be kept local (no leak outside of a narrow scope) and certainly not shared by multiple threads. Luc P. Excuse my ignorance but does volatile! have anything to do with Java's volatile keyword? Is there any relation at all? I'm not suggesting a name change, but it can be confusing coming from that angle. Maybe a blurb in the doc string? -- 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. -- Luc Prefontainelprefonta...@softaddicts.ca sent by ibisMail! -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
No, it means exactly the same thing as volatile in Java (and is implemented in the Volatile Java class which holds a single volatile field). Basically a volatile box since a field must exist inside a class. The semantics are the same as Java - writes are guaranteed to be seen by subsequent reads on any thread (that property is not guaranteed by a non-volatile field). vswap! on a volatile is syntactically similar to swap! on an atom but without the atomicity guarantees. That is, vswap! consists of a read followed by a write but this is non-transactional so another thread could change the value in between. In other words: don't use this unless you can enforce thread isolation or safety through other means. Thus, volatiles are dangerous *by default*, unlike every other stateful thing in Clojure. Some stateful transducers use volatiles for performance and provide thread isolation via how they are constructed and used. On Tuesday, September 9, 2014 12:06:36 PM UTC-5, Luc wrote: The keyword has different meaning depending on the language and context. Most of the time to prevent optimizations by the compiler to insure write ordering and some consistent view (Java use). Not here. It's meant to warn that nothing is guaranteed, no synchronization, no consistent view. It should be kept local (no leak outside of a narrow scope) and certainly not shared by multiple threads. Luc P. Excuse my ignorance but does volatile! have anything to do with Java's volatile keyword? Is there any relation at all? I'm not suggesting a name change, but it can be confusing coming from that angle. Maybe a blurb in the doc string? -- 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. -- Luc Prefontainelprefo...@softaddicts.ca javascript: sent by ibisMail! -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
Hello, I posted a question about volatiles on the github commit: https://github.com/clojure/clojure/commit/60440977823752f13a3fec3637538e9a1d68c5d4 I don't know if anybody noticed, so... why is volatile created with function volatile! and not volatile ? Atoms, refs and agents don't have exclamation mark in their constructor functions. Should I think about volatiles as mutable locals? :-) František On Friday, September 5, 2014 4:26:53 PM UTC+2, Alex Miller wrote: Clojure 1.7.0-alpha1 is now available. Try it via - Download: http://central.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Download securely: https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Leiningen: [org.clojure/clojure 1.7.0-alpha2] Highlights below, full change log here: https://github.com/clojure/clojure/blob/master/changes.md For users of Clojure 1.7.0-alpha1, there have been a few important changes in transducers since alpha1: - Removed flatmap transducer - Added cat transducer - mapcat 1-arity is now a transducer, specifically: (comp (map f) cat) - The completing function has been lifted to be public Clojure 1.7.0-alpha2 has the changes below from 1.6.0: ## 1 New and Improved Features ### 1.1 Transducers Transducers is a new way to decouple algorithmic transformations from their application in different contexts. Transducers are functions that transform reducing functions to build up a recipe for transformation. Also see: http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming Many existing sequence functions now have a new arity (one fewer argument than before). This arity will return a transducer that represents the same logic but is independent of lazy sequence processing. Functions included are: * conj (conjs to []) * map * mapcat * filter * remove * take * take-while * drop * drop-while * cycle * take-nth * replace * partition-by * partition-all * keep * keep-indexed Additionally some new transducer functions have been added: * cat - concatenates the contents of each input * de-dupe - removes consecutive duplicated values * random-sample - returns items from coll with random probability And this function can be used to make completing transforms: * completing There are also several new or modified functions that can be used to apply transducers in different ways: * sequence - takes a transformation and a coll and produces a lazy seq * transduce - reduce with a transformation (eager) * iteration - returns an iterable/seqable/reducible seq of applications of the transducer to items in coll. Applications are re-performed with every iterator/seq/reduce. * run! - run the transformation for side effects on the collection There have been a number of internal changes to support transducers: * volatiles - there are a new set of functions (volatile!, vswap!, vreset!, volatile?) to create and use volatile boxes to hold state in stateful transducers. Volatiles are faster than atoms but give up atomicity guarantees so should only be used with thread isolation. * array iterators - added support for iterators over arrays Some issues created and addressed during development: * [CLJ-1511](http://dev.clojure.org/jira/browse/CLJ-1511) * [CLJ-1497](http://dev.clojure.org/jira/browse/CLJ-1497) ### 1.2 Keyword and Symbol Construction In response to issues raised in [CLJ-1439]( http://dev.clojure.org/jira/browse/CLJ-1439), several changes have been made in symbol and keyword construction: 1) The main bottleneck in construction of symbols (which also occurs inside keywords) was interning of the name and namespace strings. This interning has been removed, resulting in a performance increase. 2) Keywords are cached and keyword construction includes a cache check. A change was made to only clear the cache reference queue when there is a cache miss. ### 1.3 Warn on Boxed Math One source of performance issues is the (unintended) use of arithmetic operations on boxed numbers. To make detecting the presence of boxed math easier, a warning will now be emitted about boxed math if \*unchecked-math* is enabled. Example use: user (defn plus-2 [x] (+ x 2)) ;; no warning, but boxed #'user/plus-2 user (set! *unchecked-math* true) true user (defn plus-2 [x] (+ x 2)) ;; now we see a warning Boxed math warning, NO_SOURCE_PATH:10:18 - call: public static java.lang.Number clojure.lang.Numbers.unchecked_add(java.lang.Object,long). #'user/plus-2 user (defn plus-2 [^long x] (+ x 2)) ;; use a hint to avoid boxing #'user/plus-2 * [CLJ-1325](http://dev.clojure.org/jira/browse/CLJ-1325) ### 1.4 update - like update-in for first level `update` is a new function that is like update-in specifically for first-level keys: (update m k f args...) Example use: user (update {:a 1} :a inc) {:a 2} user (update {:a 1} :a + 2) {:a 3} user (update {} :a identity) ;;
Re: [ANN] Clojure 1.7.0-alpha2
FYI the ticket about volatile is at http://dev.clojure.org/jira/browse/CLJ-1512 and the same question was raised there. On Mon, Sep 8, 2014 at 4:25 PM, Frantisek Sodomka fsodo...@gmail.com wrote: Hello, I posted a question about volatiles on the github commit: https://github.com/clojure/clojure/commit/60440977823752f13a3fec3637538e9a1d68c5d4 I don't know if anybody noticed, so... why is volatile created with function volatile! and not volatile ? Atoms, refs and agents don't have exclamation mark in their constructor functions. Should I think about volatiles as mutable locals? :-) František On Friday, September 5, 2014 4:26:53 PM UTC+2, Alex Miller wrote: Clojure 1.7.0-alpha1 is now available. Try it via - Download: http://central.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Download securely: https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Leiningen: [org.clojure/clojure 1.7.0-alpha2] Highlights below, full change log here: https://github.com/clojure/clojure/blob/master/changes.md For users of Clojure 1.7.0-alpha1, there have been a few important changes in transducers since alpha1: - Removed flatmap transducer - Added cat transducer - mapcat 1-arity is now a transducer, specifically: (comp (map f) cat) - The completing function has been lifted to be public Clojure 1.7.0-alpha2 has the changes below from 1.6.0: ## 1 New and Improved Features ### 1.1 Transducers Transducers is a new way to decouple algorithmic transformations from their application in different contexts. Transducers are functions that transform reducing functions to build up a recipe for transformation. Also see: http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming Many existing sequence functions now have a new arity (one fewer argument than before). This arity will return a transducer that represents the same logic but is independent of lazy sequence processing. Functions included are: * conj (conjs to []) * map * mapcat * filter * remove * take * take-while * drop * drop-while * cycle * take-nth * replace * partition-by * partition-all * keep * keep-indexed Additionally some new transducer functions have been added: * cat - concatenates the contents of each input * de-dupe - removes consecutive duplicated values * random-sample - returns items from coll with random probability And this function can be used to make completing transforms: * completing There are also several new or modified functions that can be used to apply transducers in different ways: * sequence - takes a transformation and a coll and produces a lazy seq * transduce - reduce with a transformation (eager) * iteration - returns an iterable/seqable/reducible seq of applications of the transducer to items in coll. Applications are re-performed with every iterator/seq/reduce. * run! - run the transformation for side effects on the collection There have been a number of internal changes to support transducers: * volatiles - there are a new set of functions (volatile!, vswap!, vreset!, volatile?) to create and use volatile boxes to hold state in stateful transducers. Volatiles are faster than atoms but give up atomicity guarantees so should only be used with thread isolation. * array iterators - added support for iterators over arrays Some issues created and addressed during development: * [CLJ-1511](http://dev.clojure.org/jira/browse/CLJ-1511) * [CLJ-1497](http://dev.clojure.org/jira/browse/CLJ-1497) ### 1.2 Keyword and Symbol Construction In response to issues raised in [CLJ-1439](http://dev.clojure.org/jira/browse/CLJ-1439), several changes have been made in symbol and keyword construction: 1) The main bottleneck in construction of symbols (which also occurs inside keywords) was interning of the name and namespace strings. This interning has been removed, resulting in a performance increase. 2) Keywords are cached and keyword construction includes a cache check. A change was made to only clear the cache reference queue when there is a cache miss. ### 1.3 Warn on Boxed Math One source of performance issues is the (unintended) use of arithmetic operations on boxed numbers. To make detecting the presence of boxed math easier, a warning will now be emitted about boxed math if \*unchecked-math* is enabled. Example use: user (defn plus-2 [x] (+ x 2)) ;; no warning, but boxed #'user/plus-2 user (set! *unchecked-math* true) true user (defn plus-2 [x] (+ x 2)) ;; now we see a warning Boxed math warning, NO_SOURCE_PATH:10:18 - call: public static java.lang.Number clojure.lang.Numbers.unchecked_add(java.lang.Object,long). #'user/plus-2 user (defn plus-2 [^long x] (+ x 2)) ;; use a hint to avoid boxing #'user/plus-2 * [CLJ-1325](http://dev.clojure.org/jira/browse/CLJ-1325) ### 1.4 update - like update-in for first level `update` is a new function that is like update-in specifically
Re: [ANN] Clojure 1.7.0-alpha2
I asked Rich and he said making a volatile is as dangerous as any ! op. Some people have also asked about vswap! being a macro instead of a method on Volatile. The issue there is that vswap! takes a variadic number of update function args. If implemented as a method, you'd need to provide multiple arities or eventually use apply (like in Atom's swap! https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Atom.java#L79) - doing it in a macro lets that expansion take place at compile time to provide better performance without the apply. On Mon, Sep 8, 2014 at 1:36 PM, Jozef Wagner jozef.wag...@gmail.com wrote: FYI the ticket about volatile is at http://dev.clojure.org/jira/browse/CLJ-1512 and the same question was raised there. On Mon, Sep 8, 2014 at 4:25 PM, Frantisek Sodomka fsodo...@gmail.com wrote: Hello, I posted a question about volatiles on the github commit: https://github.com/clojure/clojure/commit/60440977823752f13a3fec3637538e9a1d68c5d4 I don't know if anybody noticed, so... why is volatile created with function volatile! and not volatile ? Atoms, refs and agents don't have exclamation mark in their constructor functions. Should I think about volatiles as mutable locals? :-) František On Friday, September 5, 2014 4:26:53 PM UTC+2, Alex Miller wrote: Clojure 1.7.0-alpha1 is now available. Try it via - Download: http://central.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Download securely: https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Leiningen: [org.clojure/clojure 1.7.0-alpha2] Highlights below, full change log here: https://github.com/clojure/clojure/blob/master/changes.md For users of Clojure 1.7.0-alpha1, there have been a few important changes in transducers since alpha1: - Removed flatmap transducer - Added cat transducer - mapcat 1-arity is now a transducer, specifically: (comp (map f) cat) - The completing function has been lifted to be public Clojure 1.7.0-alpha2 has the changes below from 1.6.0: ## 1 New and Improved Features ### 1.1 Transducers Transducers is a new way to decouple algorithmic transformations from their application in different contexts. Transducers are functions that transform reducing functions to build up a recipe for transformation. Also see: http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming Many existing sequence functions now have a new arity (one fewer argument than before). This arity will return a transducer that represents the same logic but is independent of lazy sequence processing. Functions included are: * conj (conjs to []) * map * mapcat * filter * remove * take * take-while * drop * drop-while * cycle * take-nth * replace * partition-by * partition-all * keep * keep-indexed Additionally some new transducer functions have been added: * cat - concatenates the contents of each input * de-dupe - removes consecutive duplicated values * random-sample - returns items from coll with random probability And this function can be used to make completing transforms: * completing There are also several new or modified functions that can be used to apply transducers in different ways: * sequence - takes a transformation and a coll and produces a lazy seq * transduce - reduce with a transformation (eager) * iteration - returns an iterable/seqable/reducible seq of applications of the transducer to items in coll. Applications are re-performed with every iterator/seq/reduce. * run! - run the transformation for side effects on the collection There have been a number of internal changes to support transducers: * volatiles - there are a new set of functions (volatile!, vswap!, vreset!, volatile?) to create and use volatile boxes to hold state in stateful transducers. Volatiles are faster than atoms but give up atomicity guarantees so should only be used with thread isolation. * array iterators - added support for iterators over arrays Some issues created and addressed during development: * [CLJ-1511](http://dev.clojure.org/jira/browse/CLJ-1511) * [CLJ-1497](http://dev.clojure.org/jira/browse/CLJ-1497) ### 1.2 Keyword and Symbol Construction In response to issues raised in [CLJ-1439](http://dev.clojure.org/jira/browse/CLJ-1439), several changes have been made in symbol and keyword construction: 1) The main bottleneck in construction of symbols (which also occurs inside keywords) was interning of the name and namespace strings. This interning has been removed, resulting in a performance increase. 2) Keywords are cached and keyword construction includes a cache check. A change was made to only clear the cache reference queue when there is a cache miss. ### 1.3 Warn on Boxed Math One source of performance issues is the (unintended) use of arithmetic operations
Re: [ANN] Clojure 1.7.0-alpha2
+1 for the ! No atomic changes here, no coordination whatsoever. At the mercy of the caller... I asked Rich and he said making a volatile is as dangerous as any ! op. Some people have also asked about vswap! being a macro instead of a method on Volatile. The issue there is that vswap! takes a variadic number of update function args. If implemented as a method, you'd need to provide multiple arities or eventually use apply (like in Atom's swap! https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Atom.java#L79) - doing it in a macro lets that expansion take place at compile time to provide better performance without the apply. On Mon, Sep 8, 2014 at 1:36 PM, Jozef Wagner jozef.wag...@gmail.com wrote: FYI the ticket about volatile is at http://dev.clojure.org/jira/browse/CLJ-1512 and the same question was raised there. On Mon, Sep 8, 2014 at 4:25 PM, Frantisek Sodomka fsodo...@gmail.com wrote: Hello, I posted a question about volatiles on the github commit: https://github.com/clojure/clojure/commit/60440977823752f13a3fec3637538e9a1d68c5d4 I don't know if anybody noticed, so... why is volatile created with function volatile! and not volatile ? Atoms, refs and agents don't have exclamation mark in their constructor functions. Should I think about volatiles as mutable locals? :-) František On Friday, September 5, 2014 4:26:53 PM UTC+2, Alex Miller wrote: Clojure 1.7.0-alpha1 is now available. Try it via - Download: http://central.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Download securely: https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Leiningen: [org.clojure/clojure 1.7.0-alpha2] Highlights below, full change log here: https://github.com/clojure/clojure/blob/master/changes.md For users of Clojure 1.7.0-alpha1, there have been a few important changes in transducers since alpha1: - Removed flatmap transducer - Added cat transducer - mapcat 1-arity is now a transducer, specifically: (comp (map f) cat) - The completing function has been lifted to be public Clojure 1.7.0-alpha2 has the changes below from 1.6.0: ## 1 New and Improved Features ### 1.1 Transducers Transducers is a new way to decouple algorithmic transformations from their application in different contexts. Transducers are functions that transform reducing functions to build up a recipe for transformation. Also see: http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming Many existing sequence functions now have a new arity (one fewer argument than before). This arity will return a transducer that represents the same logic but is independent of lazy sequence processing. Functions included are: * conj (conjs to []) * map * mapcat * filter * remove * take * take-while * drop * drop-while * cycle * take-nth * replace * partition-by * partition-all * keep * keep-indexed Additionally some new transducer functions have been added: * cat - concatenates the contents of each input * de-dupe - removes consecutive duplicated values * random-sample - returns items from coll with random probability And this function can be used to make completing transforms: * completing There are also several new or modified functions that can be used to apply transducers in different ways: * sequence - takes a transformation and a coll and produces a lazy seq * transduce - reduce with a transformation (eager) * iteration - returns an iterable/seqable/reducible seq of applications of the transducer to items in coll. Applications are re-performed with every iterator/seq/reduce. * run! - run the transformation for side effects on the collection There have been a number of internal changes to support transducers: * volatiles - there are a new set of functions (volatile!, vswap!, vreset!, volatile?) to create and use volatile boxes to hold state in stateful transducers. Volatiles are faster than atoms but give up atomicity guarantees so should only be used with thread isolation. * array iterators - added support for iterators over arrays Some issues created and addressed during development: * [CLJ-1511](http://dev.clojure.org/jira/browse/CLJ-1511) * [CLJ-1497](http://dev.clojure.org/jira/browse/CLJ-1497) ### 1.2 Keyword and Symbol Construction In response to issues raised in [CLJ-1439](http://dev.clojure.org/jira/browse/CLJ-1439), several changes have been made in symbol and keyword construction: 1) The main bottleneck in construction of symbols (which also occurs inside keywords) was interning of the name and namespace strings. This interning has been removed, resulting in a performance increase. 2) Keywords are cached and keyword
Re: [ANN] Clojure 1.7.0-alpha2
If anything let's add more bangs to the name. Unlike any of atom/ref/agent, volatile! is not really part of the familiar state model. Yes it applies a function to a thing, changing the thing. Like Luc says, not atomically. The linux hdparm tool has the –yes-i-know-what-i-am-doing and --please-destroy-my-drive flags. Those could be useful. Maybe (binding [*please-randomly-break-my-application* true] ...) On Monday, September 8, 2014 3:22:48 PM UTC-4, Luc wrote: +1 for the ! No atomic changes here, no coordination whatsoever. At the mercy of the caller... I asked Rich and he said making a volatile is as dangerous as any ! op. Some people have also asked about vswap! being a macro instead of a method on Volatile. The issue there is that vswap! takes a variadic number of update function args. If implemented as a method, you'd need to provide multiple arities or eventually use apply (like in Atom's swap! https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Atom.java#L79) - doing it in a macro lets that expansion take place at compile time to provide better performance without the apply. On Mon, Sep 8, 2014 at 1:36 PM, Jozef Wagner jozef@gmail.com javascript: wrote: FYI the ticket about volatile is at http://dev.clojure.org/jira/browse/CLJ-1512 and the same question was raised there. On Mon, Sep 8, 2014 at 4:25 PM, Frantisek Sodomka fsod...@gmail.com javascript: wrote: Hello, I posted a question about volatiles on the github commit: https://github.com/clojure/clojure/commit/60440977823752f13a3fec3637538e9a1d68c5d4 I don't know if anybody noticed, so... why is volatile created with function volatile! and not volatile ? Atoms, refs and agents don't have exclamation mark in their constructor functions. Should I think about volatiles as mutable locals? :-) František On Friday, September 5, 2014 4:26:53 PM UTC+2, Alex Miller wrote: Clojure 1.7.0-alpha1 is now available. Try it via - Download: http://central.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Download securely: https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Leiningen: [org.clojure/clojure 1.7.0-alpha2] Highlights below, full change log here: https://github.com/clojure/clojure/blob/master/changes.md For users of Clojure 1.7.0-alpha1, there have been a few important changes in transducers since alpha1: - Removed flatmap transducer - Added cat transducer - mapcat 1-arity is now a transducer, specifically: (comp (map f) cat) - The completing function has been lifted to be public Clojure 1.7.0-alpha2 has the changes below from 1.6.0: ## 1 New and Improved Features ### 1.1 Transducers Transducers is a new way to decouple algorithmic transformations from their application in different contexts. Transducers are functions that transform reducing functions to build up a recipe for transformation. Also see: http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming Many existing sequence functions now have a new arity (one fewer argument than before). This arity will return a transducer that represents the same logic but is independent of lazy sequence processing. Functions included are: * conj (conjs to []) * map * mapcat * filter * remove * take * take-while * drop * drop-while * cycle * take-nth * replace * partition-by * partition-all * keep * keep-indexed Additionally some new transducer functions have been added: * cat - concatenates the contents of each input * de-dupe - removes consecutive duplicated values * random-sample - returns items from coll with random probability And this function can be used to make completing transforms: * completing There are also several new or modified functions that can be used to apply transducers in different ways: * sequence - takes a transformation and a coll and produces a lazy seq * transduce - reduce with a transformation (eager) * iteration - returns an iterable/seqable/reducible seq of applications of the transducer to items in coll. Applications are re-performed with every iterator/seq/reduce. * run! - run the transformation for side effects on the collection There have been a number of internal changes to support transducers: * volatiles - there are a new set of functions (volatile!, vswap!, vreset!, volatile?) to create and use volatile boxes to hold state in stateful transducers. Volatiles are faster than atoms but give up atomicity
Re: [ANN] Clojure 1.7.0-alpha2
Great stuff, and thanks for all the hard work. But if I may, I'd like to suggest that completing isn't a great name for that transducer helper function-- at least not in the core namespace. It's too generic: there's no way to guess what it does from the name, and IMO a function with such a niche role doesn't merit such a basic name. Granted I can't think of a slam-dunk alternative, but what about something like trans-complete? -- 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.
Re: [ANN] Clojure 1.7.0-alpha2
Obviously, that should say: Clojure 1.7.0-alpha2 is now available. On Friday, September 5, 2014 9:27:06 AM UTC-5, Alex Miller wrote: Clojure 1.7.0-alpha1 is now available. Try it via - Download: http://central.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Download securely: https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Leiningen: [org.clojure/clojure 1.7.0-alpha2] Highlights below, full change log here: https://github.com/clojure/clojure/blob/master/changes.md For users of Clojure 1.7.0-alpha1, there have been a few important changes in transducers since alpha1: - Removed flatmap transducer - Added cat transducer - mapcat 1-arity is now a transducer, specifically: (comp (map f) cat) - The completing function has been lifted to be public Clojure 1.7.0-alpha2 has the changes below from 1.6.0: ## 1 New and Improved Features ### 1.1 Transducers Transducers is a new way to decouple algorithmic transformations from their application in different contexts. Transducers are functions that transform reducing functions to build up a recipe for transformation. Also see: http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming Many existing sequence functions now have a new arity (one fewer argument than before). This arity will return a transducer that represents the same logic but is independent of lazy sequence processing. Functions included are: * conj (conjs to []) * map * mapcat * filter * remove * take * take-while * drop * drop-while * cycle * take-nth * replace * partition-by * partition-all * keep * keep-indexed Additionally some new transducer functions have been added: * cat - concatenates the contents of each input * de-dupe - removes consecutive duplicated values * random-sample - returns items from coll with random probability And this function can be used to make completing transforms: * completing There are also several new or modified functions that can be used to apply transducers in different ways: * sequence - takes a transformation and a coll and produces a lazy seq * transduce - reduce with a transformation (eager) * iteration - returns an iterable/seqable/reducible seq of applications of the transducer to items in coll. Applications are re-performed with every iterator/seq/reduce. * run! - run the transformation for side effects on the collection There have been a number of internal changes to support transducers: * volatiles - there are a new set of functions (volatile!, vswap!, vreset!, volatile?) to create and use volatile boxes to hold state in stateful transducers. Volatiles are faster than atoms but give up atomicity guarantees so should only be used with thread isolation. * array iterators - added support for iterators over arrays Some issues created and addressed during development: * [CLJ-1511](http://dev.clojure.org/jira/browse/CLJ-1511) * [CLJ-1497](http://dev.clojure.org/jira/browse/CLJ-1497) ### 1.2 Keyword and Symbol Construction In response to issues raised in [CLJ-1439]( http://dev.clojure.org/jira/browse/CLJ-1439), several changes have been made in symbol and keyword construction: 1) The main bottleneck in construction of symbols (which also occurs inside keywords) was interning of the name and namespace strings. This interning has been removed, resulting in a performance increase. 2) Keywords are cached and keyword construction includes a cache check. A change was made to only clear the cache reference queue when there is a cache miss. ### 1.3 Warn on Boxed Math One source of performance issues is the (unintended) use of arithmetic operations on boxed numbers. To make detecting the presence of boxed math easier, a warning will now be emitted about boxed math if \*unchecked-math* is enabled. Example use: user (defn plus-2 [x] (+ x 2)) ;; no warning, but boxed #'user/plus-2 user (set! *unchecked-math* true) true user (defn plus-2 [x] (+ x 2)) ;; now we see a warning Boxed math warning, NO_SOURCE_PATH:10:18 - call: public static java.lang.Number clojure.lang.Numbers.unchecked_add(java.lang.Object,long). #'user/plus-2 user (defn plus-2 [^long x] (+ x 2)) ;; use a hint to avoid boxing #'user/plus-2 * [CLJ-1325](http://dev.clojure.org/jira/browse/CLJ-1325) ### 1.4 update - like update-in for first level `update` is a new function that is like update-in specifically for first-level keys: (update m k f args...) Example use: user (update {:a 1} :a inc) {:a 2} user (update {:a 1} :a + 2) {:a 3} user (update {} :a identity) ;; missing returns nil {:a nil} * [CLJ-1251](http://dev.clojure.org/jira/browse/CLJ-1251) ## 2 Enhancements ### 2.1 Error messages * [CLJ-1261](http://dev.clojure.org/jira/browse/CLJ-1261) Invalid defrecord results in exception attributed to consuming ns instead of defrecord ns *
Re: [ANN] Clojure 1.7.0-alpha2
Since tools.analyzer, tools.analyzer.jvm and tools.emitter.jvm are all multimethod intensive, I wondered if the multimethod default value caching commit had any significant impact in their performance. After stress testing tools.emitter.jvm using clojure 1.7.0-alpha1 (no multimethod patch) and clojure 1.7.0-alpha2 (w/ multimethod patch) I've compared the results and I'm consistently getting a 15% speedup using clojure 1.7.0-alpha2. Sounds like a big win to me! Nicola Alex Miller writes: Clojure 1.7.0-alpha1 is now available. Try it via - Download: http://central.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Download securely: https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Leiningen: [org.clojure/clojure 1.7.0-alpha2] Highlights below, full change log here: https://github.com/clojure/clojure/blob/master/changes.md For users of Clojure 1.7.0-alpha1, there have been a few important changes in transducers since alpha1: - Removed flatmap transducer - Added cat transducer - mapcat 1-arity is now a transducer, specifically: (comp (map f) cat) - The completing function has been lifted to be public Clojure 1.7.0-alpha2 has the changes below from 1.6.0: ## 1 New and Improved Features ### 1.1 Transducers Transducers is a new way to decouple algorithmic transformations from their application in different contexts. Transducers are functions that transform reducing functions to build up a recipe for transformation. Also see: http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming Many existing sequence functions now have a new arity (one fewer argument than before). This arity will return a transducer that represents the same logic but is independent of lazy sequence processing. Functions included are: * conj (conjs to []) * map * mapcat * filter * remove * take * take-while * drop * drop-while * cycle * take-nth * replace * partition-by * partition-all * keep * keep-indexed Additionally some new transducer functions have been added: * cat - concatenates the contents of each input * de-dupe - removes consecutive duplicated values * random-sample - returns items from coll with random probability And this function can be used to make completing transforms: * completing There are also several new or modified functions that can be used to apply transducers in different ways: * sequence - takes a transformation and a coll and produces a lazy seq * transduce - reduce with a transformation (eager) * iteration - returns an iterable/seqable/reducible seq of applications of the transducer to items in coll. Applications are re-performed with every iterator/seq/reduce. * run! - run the transformation for side effects on the collection There have been a number of internal changes to support transducers: * volatiles - there are a new set of functions (volatile!, vswap!, vreset!, volatile?) to create and use volatile boxes to hold state in stateful transducers. Volatiles are faster than atoms but give up atomicity guarantees so should only be used with thread isolation. * array iterators - added support for iterators over arrays Some issues created and addressed during development: * [CLJ-1511](http://dev.clojure.org/jira/browse/CLJ-1511) * [CLJ-1497](http://dev.clojure.org/jira/browse/CLJ-1497) ### 1.2 Keyword and Symbol Construction In response to issues raised in [CLJ-1439]( http://dev.clojure.org/jira/browse/CLJ-1439), several changes have been made in symbol and keyword construction: 1) The main bottleneck in construction of symbols (which also occurs inside keywords) was interning of the name and namespace strings. This interning has been removed, resulting in a performance increase. 2) Keywords are cached and keyword construction includes a cache check. A change was made to only clear the cache reference queue when there is a cache miss. ### 1.3 Warn on Boxed Math One source of performance issues is the (unintended) use of arithmetic operations on boxed numbers. To make detecting the presence of boxed math easier, a warning will now be emitted about boxed math if \*unchecked-math* is enabled. Example use: user (defn plus-2 [x] (+ x 2)) ;; no warning, but boxed #'user/plus-2 user (set! *unchecked-math* true) true user (defn plus-2 [x] (+ x 2)) ;; now we see a warning Boxed math warning, NO_SOURCE_PATH:10:18 - call: public static java.lang.Number clojure.lang.Numbers.unchecked_add(java.lang.Object,long). #'user/plus-2 user (defn plus-2 [^long x] (+ x 2)) ;; use a hint to avoid boxing #'user/plus-2 * [CLJ-1325](http://dev.clojure.org/jira/browse/CLJ-1325) ### 1.4 update - like update-in for first level `update` is a new function that is like update-in specifically for first-level keys: (update m k f args...) Example use: user (update {:a 1} :a inc) {:a 2} user (update {:a 1} :a + 2) {:a 3} user (update {} :a identity) ;;
Re: [ANN] Clojure 1.7.0-alpha2
Excellent, great to hear it! Big thanks to Anton who posted it on Twitter originally (https://twitter.com/PieCalculus/status/468621724205203456) and then took the time to send me a beautiful smoking gun report for reproducibility. The rest was easy. On Fri, Sep 5, 2014 at 8:34 PM, Nicola Mometto brobro...@gmail.com wrote: Since tools.analyzer, tools.analyzer.jvm and tools.emitter.jvm are all multimethod intensive, I wondered if the multimethod default value caching commit had any significant impact in their performance. After stress testing tools.emitter.jvm using clojure 1.7.0-alpha1 (no multimethod patch) and clojure 1.7.0-alpha2 (w/ multimethod patch) I've compared the results and I'm consistently getting a 15% speedup using clojure 1.7.0-alpha2. Sounds like a big win to me! Nicola Alex Miller writes: Clojure 1.7.0-alpha1 is now available. Try it via - Download: http://central.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Download securely: https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ - Leiningen: [org.clojure/clojure 1.7.0-alpha2] Highlights below, full change log here: https://github.com/clojure/clojure/blob/master/changes.md For users of Clojure 1.7.0-alpha1, there have been a few important changes in transducers since alpha1: - Removed flatmap transducer - Added cat transducer - mapcat 1-arity is now a transducer, specifically: (comp (map f) cat) - The completing function has been lifted to be public Clojure 1.7.0-alpha2 has the changes below from 1.6.0: ## 1 New and Improved Features ### 1.1 Transducers Transducers is a new way to decouple algorithmic transformations from their application in different contexts. Transducers are functions that transform reducing functions to build up a recipe for transformation. Also see: http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming Many existing sequence functions now have a new arity (one fewer argument than before). This arity will return a transducer that represents the same logic but is independent of lazy sequence processing. Functions included are: * conj (conjs to []) * map * mapcat * filter * remove * take * take-while * drop * drop-while * cycle * take-nth * replace * partition-by * partition-all * keep * keep-indexed Additionally some new transducer functions have been added: * cat - concatenates the contents of each input * de-dupe - removes consecutive duplicated values * random-sample - returns items from coll with random probability And this function can be used to make completing transforms: * completing There are also several new or modified functions that can be used to apply transducers in different ways: * sequence - takes a transformation and a coll and produces a lazy seq * transduce - reduce with a transformation (eager) * iteration - returns an iterable/seqable/reducible seq of applications of the transducer to items in coll. Applications are re-performed with every iterator/seq/reduce. * run! - run the transformation for side effects on the collection There have been a number of internal changes to support transducers: * volatiles - there are a new set of functions (volatile!, vswap!, vreset!, volatile?) to create and use volatile boxes to hold state in stateful transducers. Volatiles are faster than atoms but give up atomicity guarantees so should only be used with thread isolation. * array iterators - added support for iterators over arrays Some issues created and addressed during development: * [CLJ-1511](http://dev.clojure.org/jira/browse/CLJ-1511) * [CLJ-1497](http://dev.clojure.org/jira/browse/CLJ-1497) ### 1.2 Keyword and Symbol Construction In response to issues raised in [CLJ-1439]( http://dev.clojure.org/jira/browse/CLJ-1439), several changes have been made in symbol and keyword construction: 1) The main bottleneck in construction of symbols (which also occurs inside keywords) was interning of the name and namespace strings. This interning has been removed, resulting in a performance increase. 2) Keywords are cached and keyword construction includes a cache check. A change was made to only clear the cache reference queue when there is a cache miss. ### 1.3 Warn on Boxed Math One source of performance issues is the (unintended) use of arithmetic operations on boxed numbers. To make detecting the presence of boxed math easier, a warning will now be emitted about boxed math if \*unchecked-math* is enabled. Example use: user (defn plus-2 [x] (+ x 2)) ;; no warning, but boxed #'user/plus-2 user (set! *unchecked-math* true) true user (defn plus-2 [x] (+ x 2)) ;; now we see a warning Boxed math warning, NO_SOURCE_PATH:10:18 - call: public static java.lang.Number