Re: ANN: clj-schema, Schemas For Clojure Maps
Christophe, one thing I've wondered about the design of clj-schema is whether the schema is even the right place for determining looseness or strictness. In some sense that is a property of the validation process. It sometimes makes sense to use the same schema, but in some cases validate it loosely or in other cases validate it strictly. Laurent, what keeps you from just using `def-loose-schema`? On Mon, Dec 10, 2012 at 1:02 AM, Christophe Grand christo...@cgrand.netwrote: Oh and clj-schema is really something I would use and promote. On Mon, Dec 10, 2012 at 10:01 AM, Christophe Grand christo...@cgrand.netwrote: Hi Alex, To echo Laurent's concern: if you use schema to validate inputs you get from another (sub)system then, in my opinion, a loose schema is a better fit. It's the must-understand/must-ignore schism once again. Must-ignore (loose schemas) requires care when revising a schema (since any piece of data valid under both schemas should not have its semantics altered) but allows for forward-compatibility and, as such, reduces coupling. Regarding your use-case (validation before storing): I see two complected concerns: ensuring that you don't store bad data and ensuring that you don't store too much. So, couldn't a loose schema be sued to first validate the piece of data and then (or at the same time) prune extra keys? My two cents, Christophe On Sun, Dec 9, 2012 at 9:45 PM, Alex Baranosky alexander.barano...@gmail.com wrote: Hi Laurent, It was originally written as loose-only, because that is an easier problem to solve, but since these schemas are being used at work to make sure no bad data gets stored in HBase we decided collectively that strictness was more of what we wanted. I'm open to exploring ways to make the default behavior of defschema be loose, perhaps via a binding. I could then create a third macro `def-strict-schema`... Let me know if you have any thoughts on approaches for this kind of modification. In general I'm open to ideas that help the library be more useful to people for their projects, so please feel free to shoot ideas by me. Alex On Sun, Dec 9, 2012 at 10:30 AM, Ambrose Bonnaire-Sergeant abonnaireserge...@gmail.com wrote: I think Typed Clojure and clj-schema could work very nicely together. I'll look at it again in a few months. Thanks, Ambrose On Wed, Nov 28, 2012 at 11:18 AM, Alex Baranosky alexander.barano...@gmail.com wrote: Hi Stathis, Thanks for your interestin clj-schema. If you use it and have any feedback please let me know. clj-schema is released under the MIT license: http://mit-license.org/ I think TypedClojure is really cool. I'm excited about both approaches because in general I'm very interested in approaches to coding that help us ensure that our code works correctly. That said there are some interesting differences in the approaches: - schemas can be used for other things other than validation or type checking. - schemas are more decoupled from the code. Say you are reading a map out of a file, or get a map returned from another library. With schemas you could easily validate the map. How would that be handled in a TypeClojure approach? Also, schema validation only checks at a snapshot in time; it makes no effort to ensure that that map is always correct. - schema validation happens at run-time; TypedClojure is a static analysis tool. ( Of course, if there was some kind of adapter for TypedClojure it could take schemas as params to the type declarations.) Alex On Tue, Nov 27, 2012 at 2:23 AM, Stathis Sideris side...@gmail.comwrote: Hello Alex, This looks very useful, thanks. What's the license under which you are releasing this code? Also, I'm wondering whether something like that could be the next step for Typed Clojure. From Ambrose's thesis, I got the impression that he would like Typed Clojure to eventually cater for checking the contents of maps. Thanks, Stathis On Sunday, 25 November 2012 23:22:04 UTC, Alex Baranosky wrote: Clj-schema is a library for defining and validating schemas for maps, as well as for using those schemas to create valid test data. We've been using this in production for at least a few months now, at Runa. https://github.com/runa-dev/**clj-schemahttps://github.com/runa-dev/clj-schema The main benefits I've found from using this library are: * validating the inputs to the application: validating Ring request params and config files * validating before storing maps into the DB * using the clj-schema.fixtures library to create valid test data that stays valid. So as the standard form of a map changes over time the tests will stay in sync with those changes automatically. * there are some code-readability benefits as well - any developer can pretty quickly see what certain kinds of maps tend to look like. There's more info in the README:
Re: Clojure contrib datalog
Thanks, Alexander and Bronsa! Shantanu On Monday, 10 December 2012 21:13:37 UTC+5:30, Bronsa wrote: There's also https://github.com/fogus/bacwn 2012/12/10 Alexander Solovyov alex...@solovyov.net javascript: Hi, I don't think it's maintained somewhere (at least I haven't seen anything), but at some point in past I extracted it from sources of clojure-contrib and put it on github (with few updates to code, nothing major): https://github.com/piranha/datalog On Sun, Dec 9, 2012 at 1:15 PM, Shantanu Kumar kumar.s...@gmail.comjavascript: wrote: Hi, I saw clojure-contrib datalog has not made it into modular contribs: https://github.com/clojure/clojure-contrib/tree/master/modules/datalog http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go http://dev.clojure.org/display/doc/Clojure+Contrib+Libraries Does anybody know if it's being maintained somewhere? Datomic supports datalog, so I wrongly presumed otherwise earlier. Shantanu -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: 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 -- Alexander -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: 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 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
Re: ANN: clj-schema, Schemas For Clojure Maps
2012/12/11 Alex Baranosky alexander.barano...@gmail.com Christophe, one thing I've wondered about the design of clj-schema is whether the schema is even the right place for determining looseness or strictness. In some sense that is a property of the validation process. It sometimes makes sense to use the same schema, but in some cases validate it loosely or in other cases validate it strictly. Isn't that the case already? I see that you put ::strict-schema metadata via the loose-schema / strict-schema functions ? i agree that schema could be defined without looseness / strictness information, and that it could be a property of the validation run. In order for that to play well with composition of schemas, you may have to : - make schemas loose by default - allow to define strict schemas - allow to force validation in strict mode (would be loose by default, except of course for those schemas hard-defined as stricts) Some implementation questions : - couldn't strict-schema function be defined in terms of loose-schema function ( just assoc'ing the additional key to the result of calling loose-schema ?) - would it be possible to totally free the data ? :-), e.g. make it public that creating a strict schema requires a :clj-schema.schema true metadata on the vector of paths? Cheers, -- Laurent Laurent, what keeps you from just using `def-loose-schema`? On Mon, Dec 10, 2012 at 1:02 AM, Christophe Grand christo...@cgrand.netwrote: Oh and clj-schema is really something I would use and promote. On Mon, Dec 10, 2012 at 10:01 AM, Christophe Grand christo...@cgrand.net wrote: Hi Alex, To echo Laurent's concern: if you use schema to validate inputs you get from another (sub)system then, in my opinion, a loose schema is a better fit. It's the must-understand/must-ignore schism once again. Must-ignore (loose schemas) requires care when revising a schema (since any piece of data valid under both schemas should not have its semantics altered) but allows for forward-compatibility and, as such, reduces coupling. Regarding your use-case (validation before storing): I see two complected concerns: ensuring that you don't store bad data and ensuring that you don't store too much. So, couldn't a loose schema be sued to first validate the piece of data and then (or at the same time) prune extra keys? My two cents, Christophe On Sun, Dec 9, 2012 at 9:45 PM, Alex Baranosky alexander.barano...@gmail.com wrote: Hi Laurent, It was originally written as loose-only, because that is an easier problem to solve, but since these schemas are being used at work to make sure no bad data gets stored in HBase we decided collectively that strictness was more of what we wanted. I'm open to exploring ways to make the default behavior of defschema be loose, perhaps via a binding. I could then create a third macro `def-strict-schema`... Let me know if you have any thoughts on approaches for this kind of modification. In general I'm open to ideas that help the library be more useful to people for their projects, so please feel free to shoot ideas by me. Alex On Sun, Dec 9, 2012 at 10:30 AM, Ambrose Bonnaire-Sergeant abonnaireserge...@gmail.com wrote: I think Typed Clojure and clj-schema could work very nicely together. I'll look at it again in a few months. Thanks, Ambrose On Wed, Nov 28, 2012 at 11:18 AM, Alex Baranosky alexander.barano...@gmail.com wrote: Hi Stathis, Thanks for your interestin clj-schema. If you use it and have any feedback please let me know. clj-schema is released under the MIT license: http://mit-license.org/ I think TypedClojure is really cool. I'm excited about both approaches because in general I'm very interested in approaches to coding that help us ensure that our code works correctly. That said there are some interesting differences in the approaches: - schemas can be used for other things other than validation or type checking. - schemas are more decoupled from the code. Say you are reading a map out of a file, or get a map returned from another library. With schemas you could easily validate the map. How would that be handled in a TypeClojure approach? Also, schema validation only checks at a snapshot in time; it makes no effort to ensure that that map is always correct. - schema validation happens at run-time; TypedClojure is a static analysis tool. ( Of course, if there was some kind of adapter for TypedClojure it could take schemas as params to the type declarations.) Alex On Tue, Nov 27, 2012 at 2:23 AM, Stathis Sideris side...@gmail.comwrote: Hello Alex, This looks very useful, thanks. What's the license under which you are releasing this code? Also, I'm wondering whether something like that could be the next step for Typed Clojure. From Ambrose's thesis, I got the impression that he would like Typed Clojure to eventually cater for
Re: abysmal multicore performance, especially on AMD processors
nicolas.o...@gmail.com nicolas.o...@gmail.com writes: What happens if your run it a third time at the end? (The question is related to the fact that there appears to be transition states between monomorphic and megamorphic call sites, which might lead to an explanation.) Same results, but your comment jogged my reading and analysis is what I believe is the right direction. This is a potentially grandiose claim, but I believe the inverse speedup is due to contention caused by JVM type profiling in megamorphic call sites. Unfortunately -XX:-UseTypeProfile doesn’t appear to turn off type profiling itself, so I can’t prove this claim definitively without going even further down the rabbit hole and grubbing through the JVM source code. To back up this claim, I present the following modified `conj*`: (defn conj* [coll x] (let [a (long-array 32)] (dotimes [n 5] (dotimes [i 32] (aset a i n))) (clojure.lang.RT/conj coll x))) And the resulting profiling numbers: list-conj* : map-ms: 42.0, pmap-ms 24.8, speedup 1.69 cons-conj* : map-ms: 39.7, pmap-ms 25.1, speedup 1.58 Adding busy-work (and an extra allocation!) to the loop improved the speed-up, I believe by decreasing the relative portion of the call execution time during which the callsite type profile information is being updated. If I’m correct, the `Cons` and `PersistentList` `.cons` implementations are so tight that in their base versions the type profiling forms a significant enough portion of the total call that the updates are in frequent conflict. Adding busy-work to the `conj*` call adds some jitter which prevents them from contending quite as frequently. I’m not sure what the next steps are. Open a bug on the JVM? This is something one can attempt to circumvent on a case-by-case basis, but IHMO has significant negative implications for Clojure’s concurrency story. -Marshall -- 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
Re: ANN: clj-schema, Schemas For Clojure Maps
Hi Laurent, I've committed some refactoring that implements defschema in terms of def-loose-schema. I also added a note to the readme explaining that :clj-schema.schema/strict true metadata is required to make a schema strict. As for the beginning part of your message, I have to mull the ideas over a little, but appreciate the ideas. Alex On Tue, Dec 11, 2012 at 1:31 AM, Laurent PETIT laurent.pe...@gmail.comwrote: 2012/12/11 Alex Baranosky alexander.barano...@gmail.com Christophe, one thing I've wondered about the design of clj-schema is whether the schema is even the right place for determining looseness or strictness. In some sense that is a property of the validation process. It sometimes makes sense to use the same schema, but in some cases validate it loosely or in other cases validate it strictly. Isn't that the case already? I see that you put ::strict-schema metadata via the loose-schema / strict-schema functions ? i agree that schema could be defined without looseness / strictness information, and that it could be a property of the validation run. In order for that to play well with composition of schemas, you may have to : - make schemas loose by default - allow to define strict schemas - allow to force validation in strict mode (would be loose by default, except of course for those schemas hard-defined as stricts) Some implementation questions : - couldn't strict-schema function be defined in terms of loose-schema function ( just assoc'ing the additional key to the result of calling loose-schema ?) - would it be possible to totally free the data ? :-), e.g. make it public that creating a strict schema requires a :clj-schema.schema true metadata on the vector of paths? Cheers, -- Laurent Laurent, what keeps you from just using `def-loose-schema`? On Mon, Dec 10, 2012 at 1:02 AM, Christophe Grand christo...@cgrand.netwrote: Oh and clj-schema is really something I would use and promote. On Mon, Dec 10, 2012 at 10:01 AM, Christophe Grand christo...@cgrand.net wrote: Hi Alex, To echo Laurent's concern: if you use schema to validate inputs you get from another (sub)system then, in my opinion, a loose schema is a better fit. It's the must-understand/must-ignore schism once again. Must-ignore (loose schemas) requires care when revising a schema (since any piece of data valid under both schemas should not have its semantics altered) but allows for forward-compatibility and, as such, reduces coupling. Regarding your use-case (validation before storing): I see two complected concerns: ensuring that you don't store bad data and ensuring that you don't store too much. So, couldn't a loose schema be sued to first validate the piece of data and then (or at the same time) prune extra keys? My two cents, Christophe On Sun, Dec 9, 2012 at 9:45 PM, Alex Baranosky alexander.barano...@gmail.com wrote: Hi Laurent, It was originally written as loose-only, because that is an easier problem to solve, but since these schemas are being used at work to make sure no bad data gets stored in HBase we decided collectively that strictness was more of what we wanted. I'm open to exploring ways to make the default behavior of defschema be loose, perhaps via a binding. I could then create a third macro `def-strict-schema`... Let me know if you have any thoughts on approaches for this kind of modification. In general I'm open to ideas that help the library be more useful to people for their projects, so please feel free to shoot ideas by me. Alex On Sun, Dec 9, 2012 at 10:30 AM, Ambrose Bonnaire-Sergeant abonnaireserge...@gmail.com wrote: I think Typed Clojure and clj-schema could work very nicely together. I'll look at it again in a few months. Thanks, Ambrose On Wed, Nov 28, 2012 at 11:18 AM, Alex Baranosky alexander.barano...@gmail.com wrote: Hi Stathis, Thanks for your interestin clj-schema. If you use it and have any feedback please let me know. clj-schema is released under the MIT license: http://mit-license.org/ I think TypedClojure is really cool. I'm excited about both approaches because in general I'm very interested in approaches to coding that help us ensure that our code works correctly. That said there are some interesting differences in the approaches: - schemas can be used for other things other than validation or type checking. - schemas are more decoupled from the code. Say you are reading a map out of a file, or get a map returned from another library. With schemas you could easily validate the map. How would that be handled in a TypeClojure approach? Also, schema validation only checks at a snapshot in time; it makes no effort to ensure that that map is always correct. - schema validation happens at run-time; TypedClojure is a static analysis tool. ( Of course, if there was some kind of adapter for TypedClojure it could
Re: ANN: clj-schema, Schemas For Clojure Maps
On Tue, Dec 11, 2012 at 9:30 AM, Alex Baranosky alexander.barano...@gmail.com wrote: Christophe, one thing I've wondered about the design of clj-schema is whether the schema is even the right place for determining looseness or strictness. In some sense that is a property of the validation process. It sometimes makes sense to use the same schema, but in some cases validate it loosely or in other cases validate it strictly. I agree: the exact same thought crossed my mind while writing the previous reply. -- On Clojure http://clj-me.cgrand.net/ Clojure Programming http://clojurebook.com Training, Consulting Contracting http://lambdanext.eu/ -- 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
Re: STM - a request for war stories
To give the full story, I should add that atoms are very natural to use and many concurrent use cases are covered by them alone. The combination of atom and immutable vector/map goes a long way and they are also useful even with mutable data, such as lazy-initialized singletons, resources that need to be re-acquired after failure, and other similar cases. In general I can say that STM transactions of very fine granularity are easy to work with because they effortlessly intertwine with mutable data and side effects. On Monday, December 10, 2012 11:39:02 AM UTC+1, Marko Topolnik wrote: The very fact that there has been no reply to this for five days may mean something. I can personally attest to STM being very difficult to put to real-life use because there is always that one thing you absolutely need for your problem, that is mutable and not transactional. Most of the time it will have to do with an existing Java library, JDK not excluded. The property of STM that it is an all-or-nothing commitment has been a show-stopper for me every time I tried to use it. My guess is, if your task is something purely computational and amenable to massive parallelization, you may have a go with STM; if it's just about business logic accessible concurrently by many clients, you won't find it workable. -- 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
Re: How things are going about expansion, class creation and loading of procedures
Mr. @athos0220 gave me a great help via twitter. https://twitter.com/athos0220/status/278439357126418432 (in Japanese) http://ideone.com/8mBm5N https://gist.github.com/4255602 Now I can write macros without class files. Thank you. With regards, Yoshinori Kohyama -- 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
Re: Interop question concerning optional args
I found this (mis)feature quite annoying too. I think, we all shall ask the language authors to fix it. On Tuesday, December 11, 2012 10:44:34 AM UTC+4, Andy Fingerhut wrote: You can pass in a length 0 array of java.nio.file.attribute.FileAttribute's like so: (java.nio.file.Files/createTempDirectory mytempname (make-array java.nio.file.attribute.FileAttribute 0)) Andy On Dec 10, 2012, at 8:54 PM, Dave Kincaid wrote: I just came across this same problem while trying to use Java 7's java.nio.file.Files.createTempDirectory() (http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#createTempDirectory(java.lang.String, java.nio.file.attribute.FileAttribute...)) Clojure won't let me just do (java.nio.file.Files/createTempDirectory mydir) It wants the FileAttribute argument. Can anyone help me get past this? I'm stuck since I really can't figure out how to create a FileAttribute. Am I better off just using Apache commons or something like that? On Monday, September 27, 2010 7:20:04 PM UTC-5, ataggart wrote: The vararg at the end of the method is just syntactic sugar for an array, so the add method actually takes 4 args, the last being a Resource array. The java compiler just replaces missing varargs with an empty array. My guess is that the reflection mechanisms in the compiler just look at type/arity. The Method object has a isVarArg() boolean, so that could be used to allow omitting varargs altogether. That would need to be an enhancement to the clojure compiler, so I opened a ticket: https://www.assembla.com/spaces/clojure/tickets/440-java-method-calls-cannot-omit-varargs On Sep 27, 1:16 pm, JonathanBelolo jonat...@scorpiomusic.fr wrote: While toying with the Sesame2.3 library, I've come across the following behavior for the first time. This is taken from the api doc for org.openrdf.repository.base.RepositoryConnectionBase: add(Resource subject, URI predicate, Value object, Resource... contexts) Adds a statement with the specified subject, predicate and object to this repository, optionally to one or more named contexts. But apparently, Clojure seems to think the optional args are mandatory... (.add con alice RDF/TYPE person) No matching method found: add for class org.openrdf.repository.sail.SailRepositoryConnection [Thrown class java.lang.IllegalArgumentException] So I run (grep #.add (.getMethods (.getClass con))) #Method public void org.openrdf.repository.base.RepositoryConnectionBase.add(org.openrdf.model. Resource,org.openrdf.model.URI,org.openrdf.model.Value, org.openrdf.model.Re source[]) throws org.openrdf.repository.RepositoryException) Finally the following works... (.add con alice RDF/TYPE person (make-array Resource 1)) nil Is this behavior normal? Are optional args mandatory when called with interop? Thanks for your help :) Jonathan -- 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 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
Re: Meaning of =
I disagree... One of the nice things about clojrue is that, at tis hear, lies the 'equiv' operator which is basically the 'egal' fn as defined by Baker [1993] [Equal rights for functional objects or the mroe things change the more they stay the same]. When using '=' with data-structures you are essentially comparing values and not types. To come back to your example, both are sequential seqs that contain the same values in the same order. Why shouldn't they be equal? Clojure would not be the language we all love, if they weren't equal... Jim On 03/10/12 06:24, Larry Travis wrote: What is the rationale for this? user (= [1 2 3 4] '(1 2 3 4)) true I was quite surprised when this turned out to be the cause of a bug in a function I am constructing. Vectors and lists differ so substantially in their implementation and in their behavior that a vector and a list should not be considered equal just because they contain the same elements in the same order. --Larry -- 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
Re: Meaning of =
From the docs: Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value,*not an identity*, comparison. hope that helps... Jim On 11/12/12 13:17, Jim foo.bar wrote: I disagree... One of the nice things about clojrue is that, at tis hear, lies the 'equiv' operator which is basically the 'egal' fn as defined by Baker [1993] [Equal rights for functional objects or the mroe things change the more they stay the same]. When using '=' with data-structures you are essentially comparing values and not types. To come back to your example, both are sequential seqs that contain the same values in the same order. Why shouldn't they be equal? Clojure would not be the language we all love, if they weren't equal... Jim On 03/10/12 06:24, Larry Travis wrote: What is the rationale for this? user (= [1 2 3 4] '(1 2 3 4)) true I was quite surprised when this turned out to be the cause of a bug in a function I am constructing. Vectors and lists differ so substantially in their implementation and in their behavior that a vector and a list should not be considered equal just because they contain the same elements in the same order. --Larry -- 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
Re: Meaning of =
If you're looking for some truly unintuitive equality behavior check this out: user= (def pred (Boolean. false)) ;;not a primitive but an object #'user/pred user= (= pred false) true user= (when pred (println I really shouldn't print)) I really shouldn't print nil Jim On 11/12/12 13:19, Jim foo.bar wrote: From the docs: Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value,*not an identity*, comparison. hope that helps... Jim On 11/12/12 13:17, Jim foo.bar wrote: I disagree... One of the nice things about clojrue is that, at tis hear, lies the 'equiv' operator which is basically the 'egal' fn as defined by Baker [1993] [Equal rights for functional objects or the mroe things change the more they stay the same]. When using '=' with data-structures you are essentially comparing values and not types. To come back to your example, both are sequential seqs that contain the same values in the same order. Why shouldn't they be equal? Clojure would not be the language we all love, if they weren't equal... Jim On 03/10/12 06:24, Larry Travis wrote: What is the rationale for this? user (= [1 2 3 4] '(1 2 3 4)) true I was quite surprised when this turned out to be the cause of a bug in a function I am constructing. Vectors and lists differ so substantially in their implementation and in their behavior that a vector and a list should not be considered equal just because they contain the same elements in the same order. --Larry -- 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
Re: Meaning of =
Apologies...I did not realise this had already been answered... oops! :-) On 11/12/12 13:32, Jim foo.bar wrote: If you're looking for some truly unintuitive equality behavior check this out: user= (def pred (Boolean. false)) ;;not a primitive but an object #'user/pred user= (= pred false) true user= (when pred (println I really shouldn't print)) I really shouldn't print nil Jim On 11/12/12 13:19, Jim foo.bar wrote: From the docs: Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value,*not an identity*, comparison. hope that helps... Jim On 11/12/12 13:17, Jim foo.bar wrote: I disagree... One of the nice things about clojrue is that, at tis hear, lies the 'equiv' operator which is basically the 'egal' fn as defined by Baker [1993] [Equal rights for functional objects or the mroe things change the more they stay the same]. When using '=' with data-structures you are essentially comparing values and not types. To come back to your example, both are sequential seqs that contain the same values in the same order. Why shouldn't they be equal? Clojure would not be the language we all love, if they weren't equal... Jim On 03/10/12 06:24, Larry Travis wrote: What is the rationale for this? user (= [1 2 3 4] '(1 2 3 4)) true I was quite surprised when this turned out to be the cause of a bug in a function I am constructing. Vectors and lists differ so substantially in their implementation and in their behavior that a vector and a list should not be considered equal just because they contain the same elements in the same order. --Larry -- 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
Re: Meaning of =
For more surprising behaviour: (= #.* #.*) Sent from my iPhone On 11 Dec 2012, at 13:32, Jim foo.bar jimpil1...@gmail.com wrote: If you're looking for some truly unintuitive equality behavior check this out: user= (def pred (Boolean. false)) ;;not a primitive but an object #'user/pred user= (= pred false) true user= (when pred (println I really shouldn't print)) I really shouldn't print nil Jim On 11/12/12 13:19, Jim foo.bar wrote: From the docs: Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison. hope that helps... Jim On 11/12/12 13:17, Jim foo.bar wrote: I disagree... One of the nice things about clojrue is that, at tis hear, lies the 'equiv' operator which is basically the 'egal' fn as defined by Baker [1993] [Equal rights for functional objects or the mroe things change the more they stay the same]. When using '=' with data-structures you are essentially comparing values and not types. To come back to your example, both are sequential seqs that contain the same values in the same order. Why shouldn't they be equal? Clojure would not be the language we all love, if they weren't equal... Jim On 03/10/12 06:24, Larry Travis wrote: What is the rationale for this? user (= [1 2 3 4] '(1 2 3 4)) true I was quite surprised when this turned out to be the cause of a bug in a function I am constructing. Vectors and lists differ so substantially in their implementation and in their behavior that a vector and a list should not be considered equal just because they contain the same elements in the same order. --Larry -- 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 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
Re: New System Architecture in Clojure
I would take a look at MIT's Pyxis for help. The publications and work sounds very similar to what you're shooting for: http://web.mit.edu/newsoffice/2012/making-web-applications-more-efficient-0831.html Paul -- 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
Re: New System Architecture in Clojure
Paul, That is exactly what I was driving at, with a slight difference. Pryxis takes an existing program with all the extra code and makes it faster. I would like to build new applications, and I don't even want to build the extra code to begin with. Naively speaking, a system that was built with primitives that were conducive to a partition graph program-analysis (from the Pryxis article) or similar, may even have more performance gains. I have studied a program analysis in the past, and it may be too difficult to do a similar analysis to start with. But at least I would like to have code annotations that would direct the code translation. The system could have a translation tool-set such that anyone could build their own translation to their favorite technology. I have a few ideas about what primitives I'd like but I wanted to hear what others have to say. I do very much appreciate the link, I'll definitely take a deep look at Pryxis. On Tuesday, December 11, 2012 9:09:20 AM UTC-6, Paul deGrandis wrote: I would take a look at MIT's Pyxis for help. The publications and work sounds very similar to what you're shooting for: http://web.mit.edu/newsoffice/2012/making-web-applications-more-efficient-0831.html Paul -- 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
Re: abysmal multicore performance, especially on AMD processors
On Dec 11, 2012, at 4:37 AM, Marshall Bockrath-Vandegrift wrote: I’m not sure what the next steps are. Open a bug on the JVM? This is something one can attempt to circumvent on a case-by-case basis, but IHMO has significant negative implications for Clojure’s concurrency story. I've gotten a bit lost in some of the diagnoses and experimental results and analyses and suggestions -- all of which I really appreciate! -- but I'm trying to get clear in my mind what the current state of things is from an application perspective. Is the following a fair characterization pending further developments? --- If you have a cons-intensive task then even if it can be divided into completely independent, long-running subtasks, there is currently no known way to get significant speedups by running the subtasks on multiple cores within a single Clojure process. In some cases you will be able to get significant speedups by separating the subtasks completely and running them in separate Clojure processes running on separate JVM instances. But the speedups will be lost (mostly, and you might even experience slowdowns) if you try to run them from within a single Clojure process. --- Or have I missed a currently-available work-around among the many suggestions? I realize that even if this is the current situation it might change via fixes on any one of several fronts (and I hope that it does!), but is this indeed the current situation? Thanks so much, -Lee -- 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
Re: No show?
This is a good workaround—however, I still wish repl-utils/show was still there. It was nice to always have it there instead doing this defn every time I need it to explore a Java API. On Sat, Feb 11, 2012 at 6:30 PM, Michał Marczyk michal.marc...@gmail.comwrote: On 11 February 2012 10:35, Ken Restivo k...@restivo.org wrote: = (clojure.pprint/print-table (clojure.reflect/reflect Math)) ClassCastException clojure.lang.Keyword cannot be cast to java.util.Map$Entry clojure.lang.APersistentMap$KeySeq.first (APersistentMap.java:132) print-table expects a sequence of maps, e.g. (print-table (:members (reflect Math))) or (print-table (:members (reflect Math :ancestors true))) to include inherited members. Sincerely, Michał -- 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 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
Re: [ANN]First toy-project : CYASUS
I tried to run this using git clone git://github.com/Yakulu/cyasus.git lein deps lein run And got a failure with this exception: Exception in thread main java.lang.ClassNotFoundException: cyasus.config, compiling:(cyasus/common.clj:8) Did you forget to check in a file? Also do you have the app running somewhere? It would be nice to see it running before analyzing the code too deeply. Asim On Mon, Nov 26, 2012 at 8:27 PM, Fabien Bourgeois fbourge...@yaltik.comwrote: Good morning ! New at once to : - Clojure - functional programming - JVM and Java ecosystem - GIT I've decided to start quietly with a micro-project : a very original URL shortener. Its name is CYASUS (for Clojure Yet Another Stupid URL Shortener) and you can find it at https://github.com/Yakulu/**cyasushttps://github.com/Yakulu/cyasus . Here are its characteristics : - published under MIT license - web application without any *script - in-memory database, strongly inspired from the Clojure Programming book sample - URL shortening, with a user-given key or an auto-generated one - already shortened URL as a list on homepage - automatic redirection or not (by configuration) - ridiculous unit testing (weak coverage) - a very approximative english-speaking (sorry about that) Its dependencies : - Ring and Compojure - Enlive - Bootstrap I think there are million of things wrong in CYASUS. If some of yourselves have a little time to spend, I will be very happy to have feedbacks or every advice about : - code structuring - style, not very functional nor idiomatic for now - everything that's wrong If my brain is able to understand all these novelties, others free/libre projects will follow soon. I hope they will be better and more interesting. Thanks a lot, have a good day. -- 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+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en -- 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
Re: abysmal multicore performance, especially on AMD processors
Lee, My reading of this thread is not quite as pessimistic as yours. Here is my synthesis for the practical application developer in Clojure from reading and re-reading all of the posts above. Marshall and Cameron, please feel free to correct me if I screw anything up here royally. ;-) When running code in parallel, the fastest to slowest ways to allocate memory via Clojure (of those examined above) are: 1. Java array 2. Java linked list 3. conj onto a transient vector 4. cons onto a list 5. conj onto a vector 6. DO NOT conj onto a list EVER!!! And that's pretty much all there is to it until Marshall figures out how to hack the JVM to overcome this very subtle JIT deoptimization bug relating to polymorphic conj calls on Cons and PersistentList types. Good luck, ~Gary On Tuesday, December 11, 2012 10:37:50 AM UTC-5, Lee wrote: On Dec 11, 2012, at 4:37 AM, Marshall Bockrath-Vandegrift wrote: I’m not sure what the next steps are. Open a bug on the JVM? This is something one can attempt to circumvent on a case-by-case basis, but IHMO has significant negative implications for Clojure’s concurrency story. I've gotten a bit lost in some of the diagnoses and experimental results and analyses and suggestions -- all of which I really appreciate! -- but I'm trying to get clear in my mind what the current state of things is from an application perspective. Is the following a fair characterization pending further developments? --- If you have a cons-intensive task then even if it can be divided into completely independent, long-running subtasks, there is currently no known way to get significant speedups by running the subtasks on multiple cores within a single Clojure process. In some cases you will be able to get significant speedups by separating the subtasks completely and running them in separate Clojure processes running on separate JVM instances. But the speedups will be lost (mostly, and you might even experience slowdowns) if you try to run them from within a single Clojure process. --- Or have I missed a currently-available work-around among the many suggestions? I realize that even if this is the current situation it might change via fixes on any one of several fronts (and I hope that it does!), but is this indeed the current situation? Thanks so much, -Lee -- 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
Re: abysmal multicore performance, especially on AMD processors
Lee Spector lspec...@hampshire.edu writes: Is the following a fair characterization pending further developments? If you have a cons-intensive task then even if it can be divided into completely independent, long-running subtasks, there is currently no known way to get significant speedups by running the subtasks on multiple cores within a single Clojure process. Not quite. If you’d been using `cons` (in the benchmark, if `reverse` used `cons` in its implementation), then you’d be getting a perfectly reasonable speedup. The problem child in this instance is `conj`. If my analysis is correct, then the issue is any megamodal call site – such as `conj` – which is invoked in a tight loop by multiple threads simultaneously. Any simultaneous invocation of such call sites introduces contention and reduces speedup, but the problem only becomes pathological in very, very tight loops, such as when performing the minimal work required by the `.cons` [1] implementations of `Cons` and `PersistentList`. In these cases the portion of the call which introduces contention is a sufficient proportion of the overall call time that the speedup becomes inverse. In some cases you will be able to get significant speedups by separating the subtasks completely and running them in separate Clojure processes running on separate JVM instances. But the speedups will be lost (mostly, and you might even experience slowdowns) if you try to run them from within a single Clojure process. For this particular issue, splitting each task into a separate JVM entirely negates the problem, because there is no simultaneous invocation of the same call site. Or have I missed a currently-available work-around among the many suggestions? You can specialize your application to avoid megamodal call sites in tight loops. If you are working with `Cons`-order sequences, just use `cons` instead of `conj`. If you are working with vectors, create your own private implementation of `conj` which you *only* call on vectors. If you are depending on operations which may/do use `conj` in tight loops, create your own private re-implementations which don’t, such as with any of the faster versions of `reverse` earlier in this thread. This is suboptimal, but it’s totally possible to work around the issue with a little bit of analysis and profiling. [1] Possible point of confusion – the JVM interface method invoked by the Clojure `conj` function is named `.cons`, for I assume historical reasons. The Clojure `cons` function on the other hand just allocates a `Cons` object in an entirely monomodal fashion. -Marshall -- 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
Vector of different refs?
Hi, How do I create a vector of different refs? I would like to have a vector with in each cell a ref so that I can manipulate them independently from each other (Is that a good idea anyway?). But when I do (def x (into [] (repeat 10 (ref 100 I end up with the same ref ten times (not surprisingly), but I would like to have ten different refs instead. TIA, Thomas -- 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
Re: Vector of different refs?
(repeatedly 10 #(ref 100)) Ray. On 11 December 2012 16:44, Thomas th.vanderv...@gmail.com wrote: Hi, How do I create a vector of different refs? I would like to have a vector with in each cell a ref so that I can manipulate them independently from each other (Is that a good idea anyway?). But when I do (def x (into [] (repeat 10 (ref 100 I end up with the same ref ten times (not surprisingly), but I would like to have ten different refs instead. TIA, Thomas -- 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 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
Re: Vector of different refs?
To answer your question: (def x (into [] (map (fn [x] (ref 100)) (range 10 Or, instead of map into, use mapv. But yes, 90% of the time you are better served by putting the entire vector in a single ref. Try using as little mutable state as possible, and you'll often find that good design just falls into place. Timothy Baldridge On Tue, Dec 11, 2012 at 9:44 AM, Thomas th.vanderv...@gmail.com wrote: Hi, How do I create a vector of different refs? I would like to have a vector with in each cell a ref so that I can manipulate them independently from each other (Is that a good idea anyway?). But when I do (def x (into [] (repeat 10 (ref 100 I end up with the same ref ten times (not surprisingly), but I would like to have ten different refs instead. TIA, Thomas -- 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 -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to 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
Re: abysmal multicore performance, especially on AMD processors
On Dec 11, 2012, at 11:40 AM, Marshall Bockrath-Vandegrift wrote: Or have I missed a currently-available work-around among the many suggestions? You can specialize your application to avoid megamodal call sites in tight loops. If you are working with `Cons`-order sequences, just use `cons` instead of `conj`. If you are working with vectors, create your own private implementation of `conj` which you *only* call on vectors. If you are depending on operations which may/do use `conj` in tight loops, create your own private re-implementations which don’t, such as with any of the faster versions of `reverse` earlier in this thread. This is suboptimal, but it’s totally possible to work around the issue with a little bit of analysis and profiling. Very informative. Thanks and thanks also to Gary. If the application does lots of list processing but does so with a mix of Clojure list and sequence manipulation functions, then one would have to write private, list/cons-only versions of all of these things? That is -- overstating it a bit, to be sure, but perhaps not entirely unfairly -- re-implement Clojure's Lisp? -Lee -- 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
Re: [ANN]First toy-project : CYASUS
I had the same problem. I changed line 8 in common.clj as follows: it was: (def params cyasus.config/params) changed to: (def params cyasus-ring.config/params) because it looked like the namespace in config.clj was cyasus-ring not cyasus. This worked for me, but I've only been using Clojure for about 30 minutes so I might have just gotten lucky. Rog On Tuesday, December 11, 2012 11:01:24 AM UTC-5, Asim Jalis wrote: I tried to run this using git clone git://github.com/Yakulu/cyasus.git lein deps lein run And got a failure with this exception: Exception in thread main java.lang.ClassNotFoundException: cyasus.config, compiling:(cyasus/common.clj:8) Did you forget to check in a file? Also do you have the app running somewhere? It would be nice to see it running before analyzing the code too deeply. Asim On Mon, Nov 26, 2012 at 8:27 PM, Fabien Bourgeois fbour...@yaltik.comjavascript: wrote: Good morning ! New at once to : - Clojure - functional programming - JVM and Java ecosystem - GIT I've decided to start quietly with a micro-project : a very original URL shortener. Its name is CYASUS (for Clojure Yet Another Stupid URL Shortener) and you can find it at https://github.com/Yakulu/**cyasushttps://github.com/Yakulu/cyasus . Here are its characteristics : - published under MIT license - web application without any *script - in-memory database, strongly inspired from the Clojure Programming book sample - URL shortening, with a user-given key or an auto-generated one - already shortened URL as a list on homepage - automatic redirection or not (by configuration) - ridiculous unit testing (weak coverage) - a very approximative english-speaking (sorry about that) Its dependencies : - Ring and Compojure - Enlive - Bootstrap I think there are million of things wrong in CYASUS. If some of yourselves have a little time to spend, I will be very happy to have feedbacks or every advice about : - code structuring - style, not very functional nor idiomatic for now - everything that's wrong If my brain is able to understand all these novelties, others free/libre projects will follow soon. I hope they will be better and more interesting. Thanks a lot, have a good day. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: 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=enhttp://groups.google.com/group/clojure?hl=en -- 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
Re: Meaning of =
I added some text to the macro if on ClojureDocs.org last time this issue was discussed on the email list. It is a bit wordy, but does also mention that this is something the Java docs themselves warn about. http://clojuredocs.org/clojure_core/clojure.core/if Andy On Dec 11, 2012, at 5:38 AM, Jim foo.bar wrote: Apologies...I did not realise this had already been answered... oops! :-) On 11/12/12 13:32, Jim foo.bar wrote: If you're looking for some truly unintuitive equality behavior check this out: user= (def pred (Boolean. false)) ;;not a primitive but an object #'user/pred user= (= pred false) true user= (when pred (println I really shouldn't print)) I really shouldn't print nil Jim On 11/12/12 13:19, Jim foo.bar wrote: From the docs: Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison. hope that helps... Jim On 11/12/12 13:17, Jim foo.bar wrote: I disagree... One of the nice things about clojrue is that, at tis hear, lies the 'equiv' operator which is basically the 'egal' fn as defined by Baker [1993] [Equal rights for functional objects or the mroe things change the more they stay the same]. When using '=' with data-structures you are essentially comparing values and not types. To come back to your example, both are sequential seqs that contain the same values in the same order. Why shouldn't they be equal? Clojure would not be the language we all love, if they weren't equal... Jim On 03/10/12 06:24, Larry Travis wrote: What is the rationale for this? user (= [1 2 3 4] '(1 2 3 4)) true I was quite surprised when this turned out to be the cause of a bug in a function I am constructing. Vectors and lists differ so substantially in their implementation and in their behavior that a vector and a list should not be considered equal just because they contain the same elements in the same order. --Larry -- 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 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
Re: Interop question concerning optional args
There is a ticket filed for it, in case some contributor wants to update the patches for it. It got intertwined with CLJ-445's patch, which hasn't been updated in a while, so you might want to start fresh rather than untangle the history there. http://dev.clojure.org/jira/browse/CLJ-440 Andy On Dec 11, 2012, at 4:30 AM, Vladimir Tsichevski wrote: I found this (mis)feature quite annoying too. I think, we all shall ask the language authors to fix it. On Tuesday, December 11, 2012 10:44:34 AM UTC+4, Andy Fingerhut wrote: You can pass in a length 0 array of java.nio.file.attribute.FileAttribute's like so: (java.nio.file.Files/createTempDirectory mytempname (make-array java.nio.file.attribute.FileAttribute 0)) Andy On Dec 10, 2012, at 8:54 PM, Dave Kincaid wrote: I just came across this same problem while trying to use Java 7's java.nio.file.Files.createTempDirectory() (http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#createTempDirectory(java.lang.String, java.nio.file.attribute.FileAttribute...)) Clojure won't let me just do (java.nio.file.Files/createTempDirectory mydir) It wants the FileAttribute argument. Can anyone help me get past this? I'm stuck since I really can't figure out how to create a FileAttribute. Am I better off just using Apache commons or something like that? On Monday, September 27, 2010 7:20:04 PM UTC-5, ataggart wrote: The vararg at the end of the method is just syntactic sugar for an array, so the add method actually takes 4 args, the last being a Resource array. The java compiler just replaces missing varargs with an empty array. My guess is that the reflection mechanisms in the compiler just look at type/arity. The Method object has a isVarArg() boolean, so that could be used to allow omitting varargs altogether. That would need to be an enhancement to the clojure compiler, so I opened a ticket: https://www.assembla.com/spaces/clojure/tickets/440-java-method-calls-cannot-omit-varargs On Sep 27, 1:16 pm, JonathanBelolo jonat...@scorpiomusic.fr wrote: While toying with the Sesame2.3 library, I've come across the following behavior for the first time. This is taken from the api doc for org.openrdf.repository.base.RepositoryConnectionBase: add(Resource subject, URI predicate, Value object, Resource... contexts) Adds a statement with the specified subject, predicate and object to this repository, optionally to one or more named contexts. But apparently, Clojure seems to think the optional args are mandatory... (.add con alice RDF/TYPE person) No matching method found: add for class org.openrdf.repository.sail.SailRepositoryConnection [Thrown class java.lang.IllegalArgumentException] So I run (grep #.add (.getMethods (.getClass con))) #Method public void org.openrdf.repository.base.RepositoryConnectionBase.add(org.openrdf.model. Resource,org.openrdf.model.URI,org.openrdf.model.Value,org.openrdf.model.Re source[]) throws org.openrdf.repository.RepositoryException) Finally the following works... (.add con alice RDF/TYPE person (make-array Resource 1)) nil Is this behavior normal? Are optional args mandatory when called with interop? Thanks for your help :) Jonathan -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To 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 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
Re: abysmal multicore performance, especially on AMD processors
Lee Spector lspec...@hampshire.edu writes: If the application does lots of list processing but does so with a mix of Clojure list and sequence manipulation functions, then one would have to write private, list/cons-only versions of all of these things? That is -- overstating it a bit, to be sure, but perhaps not entirely unfairly -- re-implement Clojure's Lisp? I just did a quick look over clojure/core.clj, and `reverse` is the only function which stood out to me as hitting the most pathological case. Every other `conj` loop over a user-provided datastructure is `conj`ing into an explicit non-list/`Cons` type. So I think if you replace your calls to `reverse` and any `conj` loops you have in your own code, you should see a perfectly reasonable speedup. -Marshall -- 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
Re: STM - a request for war stories
I am unsure whether you are writing about STM in general or in Clojure specifically. I worked for Gemstone Systems for five years on the object engine as well as applications of the distributed, multi-user, garbage-collected STM that is the centerpiece of Gemstone Smalltalk. During that time I worked with several customer applications where STM had both positive and negative contributions. If this is of interest, you can contact me directly. I can say briefly that Gemstone Smalltalk and its multi-user STM was and is being used for: 1. tracking nearly every container shipped across the Pacific ocean. 2. used to quickly develop cutting-edge financial trading instruments. 3. used to quickly develop mobile communications billing policies. 4. used to control and monitor large semiconductor fabs. 5. dispatching utility repair equipment throughout the southeastern U.S. 6. pharmaceuticals, ... 7. insurance policies, ... 8. ad hoc, distributed workflows, ... -Patrick On Sunday, December 2, 2012 8:03:53 AM UTC-8, Paul Butcher wrote: All, I have a request which I hope the members of this group are uniquely positioned to help with. I have recently started working on a new book for The Pragmatic Programmers with the working title Seven Concurrency Models in Seven Weeks (it follows on from their existing Seven Languages and Seven Databases titles). One of the approaches that I'll be covering is STM, and I'll be presenting it in Clojure. What I'd like to solicit are war stories about problems you've solved using STM, which demonstrate the strengths of the technique over and above (say) threads and locks. I'm looking for real-world examples instead of presenting yet another hackneyed atomically-make-a-bank-account-withdrawal :-) Very many thanks in advance for your help! -- paul.butcher-msgCount++ Snetterton, Castle Combe, Cadwell Park... Who says I have a one track mind? http://www.paulbutcher.com/ LinkedIn: http://www.linkedin.com/in/paulbutcher MSN: pa...@paulbutcher.com javascript: AIM: paulrabutcher Skype: paulrabutcher -- 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
Autotest for Clojure/Midje?
For a project I'm working on it would be awesome to have my tests auto-rerun after every file change. I know lazy test exists, but it doesn't work with Lein2 it seems. In the past I've used speclj with lein speclj -a. But I'd rather not use specs in this design, instead sticking with clojure's tests. Any suggestions? Thanks, Timothy -- 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
Re: Autotest for Clojure/Midje?
another option: https://github.com/jaycfields/expectations https://github.com/jakemcc/lein-autoexpect On Tue, Dec 11, 2012 at 12:38 PM, Timothy Baldridge tbaldri...@gmail.com wrote: For a project I'm working on it would be awesome to have my tests auto-rerun after every file change. I know lazy test exists, but it doesn't work with Lein2 it seems. In the past I've used speclj with lein speclj -a. But I'd rather not use specs in this design, instead sticking with clojure's tests. Any suggestions? Thanks, Timothy -- 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 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
when is a zipper better than get-in ?
I am sorry for the dumb question, but zippers are for looping over nested collections, yes? Why can't I just use get-in for that? When would I need a zipper? -- 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
Re: core.logic vs. Prolog
Is there a list of features that you'd like to implement that core.logic doesn't have yet? On Tuesday, 11 December 2012 00:52:24 UTC-5, David Nolen wrote: core.logic is still pretty young - some (many?) Prolog niceties may not be present. Don't know until you try ;) On Tue, Dec 11, 2012 at 12:29 AM, JvJ kfjwh...@gmail.com javascript:wrote: I have some code that uses Prolog, but I want to get rid of the native dependencies inherent in SWI Prolog/JPL. If I were to switch to core.logic, what would I lose and what would I gain? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: 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 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
Re: Autotest for Clojure/Midje?
On Dec 11, 2012, at 12:38 PM, Timothy Baldridge tbaldri...@gmail.com wrote: For a project I'm working on it would be awesome to have my tests auto-rerun after every file change. I know lazy test exists, but it doesn't work with Lein2 it seems. (defproject ... :profiles {:dev {:dependencies [[midje 1.4.0] [com.stuartsierra/lazytest 1.2.3]] :plugins [[lein-midje 2.0.3]]}} :repositories {stuartsierra-releases http://stuartsierra.com/maven2}) $ lein midje --lazytest I just tried this and it works. The 1.5 version of Midje will add autotesting to the new repl tools, and lein midje will then be changed to use that. At that point the old dependency on lazytest will go away. Occasional consulting on programming technique Contract programming in Ruby and Clojure Latest book: /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo -- 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
Re: when is a zipper better than get-in ?
On Dec 11, 2012, at 12:48 PM, larry google groups lawrencecloj...@gmail.com wrote: I am sorry for the dumb question, but zippers are for looping over nested collections, yes? Why can't I just use get-in for that? When would I need a zipper? If you want to edit trees, using zippers is often much much easier than collection functions. I find the code easier to understand, too. Occasional consulting on programming technique Contract programming in Ruby and Clojure Latest book: /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo -- 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
Slime and heroku setup question
I sort of got clojure interactively running and working with slime. I'd like to interactively run and test in emacs, then push to heroku. Any tutorials or pointers on how to do this? -- 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
Re: when is a zipper better than get-in ?
On Dec 11, 2012, at 1:04 PM, Brian Marick mar...@exampler.com wrote: If you want to edit trees, using zippers is often much much easier than collection functions. I find the code easier to understand, too. I almost forgot to make a shameless plug for /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo I have a chapter about zippers, with lots of exercises. (I also have a set of exercises in which you implement zippers. It's a nifty data structure.) What the heck: anyone who sends me mail this week can have $5 off. Occasional consulting on programming technique Contract programming in Ruby and Clojure Latest book: /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo -- 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
Re: STM - a request for war stories
Hi Paul, If it isn't too late to change your chapter title, I would encourage emphasizing Clojure's model of references and values in general, and the option of implementing a variety of different reference semantics that all conform to the same basic API shape. That general approach has been game-changing for me, and the STM occupies a rather small niche in the overall space. Datomic stores the entire database in an atom (not an STM ref), and updates it with a call to swap! It is literally no more complex than a trivial hackneyed book example. :-) Cheers, Stu On Sun, Dec 2, 2012 at 11:03 AM, Paul Butcher p...@paulbutcher.com wrote: All, I have a request which I hope the members of this group are uniquely positioned to help with. I have recently started working on a new book for The Pragmatic Programmers with the working title Seven Concurrency Models in Seven Weeks (it follows on from their existing Seven Languages and Seven Databases titles). One of the approaches that I'll be covering is STM, and I'll be presenting it in Clojure. What I'd like to solicit are war stories about problems you've solved using STM, which demonstrate the strengths of the technique over and above (say) threads and locks. I'm looking for real-world examples instead of presenting yet another hackneyed atomically-make-a-bank-account-withdrawal :-) Very many thanks in advance for your help! -- paul.butcher-msgCount++ Snetterton, Castle Combe, Cadwell Park... Who says I have a one track mind? http://www.paulbutcher.com/ LinkedIn: http://www.linkedin.com/in/paulbutcher MSN: p...@paulbutcher.com AIM: paulrabutcher Skype: paulrabutcher -- 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 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
Re: STM - a request for war stories
Hi Paul, Here is a real-world, production software example of the advantage of values+refs over mutable objects and locks. A Datomic user reported the following stack trace as a potential bug: 12:45:43.480 [qtp517338136-84] WARN c.v.a.s.p.e.UnknownExceptionHandler - UnknownExceptionHandler: null java.util.ConcurrentModificationException: null at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819) ~[na:1.7.0_07] at java.util.ArrayList$Itr.next(ArrayList.java:791) ~[na:1.7.0_07] at clojure.core.protocols$fn__5871.invoke(protocols.clj:76) ~[clojure-1.4.0.jar:na] at clojure.core.protocols$fn__5828$G__5823__5841.invoke(protocols.clj:13) ~[clojure-1.4.0.jar:na] at clojure.core$reduce.invoke(core.clj:6030) ~[clojure-1.4.0.jar:na] I immediately had 99% confidence that the bug was in user code, and even a pretty good idea what went wrong. A call to reduce is a functional transformation, and it expects to be passed values. The exception clearly indicates a violation of that contract, and is caused by cross-thread aliasing and mutation in the calling code. Regards, Stu On Sun, Dec 2, 2012 at 11:03 AM, Paul Butcher p...@paulbutcher.com wrote: All, I have a request which I hope the members of this group are uniquely positioned to help with. I have recently started working on a new book for The Pragmatic Programmers with the working title Seven Concurrency Models in Seven Weeks (it follows on from their existing Seven Languages and Seven Databases titles). One of the approaches that I'll be covering is STM, and I'll be presenting it in Clojure. What I'd like to solicit are war stories about problems you've solved using STM, which demonstrate the strengths of the technique over and above (say) threads and locks. I'm looking for real-world examples instead of presenting yet another hackneyed atomically-make-a-bank-account-withdrawal :-) Very many thanks in advance for your help! -- paul.butcher-msgCount++ Snetterton, Castle Combe, Cadwell Park... Who says I have a one track mind? http://www.paulbutcher.com/ LinkedIn: http://www.linkedin.com/in/paulbutcher MSN: p...@paulbutcher.com AIM: paulrabutcher Skype: paulrabutcher -- 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 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
Re: abysmal multicore performance, especially on AMD processors
OK WOW. You hit the nail on the head. It's reverse being called in a pmap that does it. When I redefine my own version of reverse (I totally cheated and just stole this) like this: (defn reverse-recursively [coll] (loop [[r more :as all] (seq coll) acc '()] (if all (recur more (cons r acc)) acc))) I speed it up from, get this, 4:32 to 0:25. Yeah. In case anybody's curious, pmap and pmapall show identical performance in this case. Wow. -Josiah On Tue, Dec 11, 2012 at 1:06 PM, Marshall Bockrath-Vandegrift llas...@gmail.com wrote: Lee Spector lspec...@hampshire.edu writes: If the application does lots of list processing but does so with a mix of Clojure list and sequence manipulation functions, then one would have to write private, list/cons-only versions of all of these things? That is -- overstating it a bit, to be sure, but perhaps not entirely unfairly -- re-implement Clojure's Lisp? I just did a quick look over clojure/core.clj, and `reverse` is the only function which stood out to me as hitting the most pathological case. Every other `conj` loop over a user-provided datastructure is `conj`ing into an explicit non-list/`Cons` type. So I think if you replace your calls to `reverse` and any `conj` loops you have in your own code, you should see a perfectly reasonable speedup. -Marshall -- 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 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
Re: abysmal multicore performance, especially on AMD processors
And, interestingly enough, suddenly the AMD FX-8350 beats the Intel Core i7 3770K, when before it was very very much not so. So for some reason, this bug was tickled more dramatically on AMD multicore processors than on Intel ones. On Tue, Dec 11, 2012 at 2:54 PM, Wm. Josiah Erikson wmjos...@gmail.comwrote: OK WOW. You hit the nail on the head. It's reverse being called in a pmap that does it. When I redefine my own version of reverse (I totally cheated and just stole this) like this: (defn reverse-recursively [coll] (loop [[r more :as all] (seq coll) acc '()] (if all (recur more (cons r acc)) acc))) I speed it up from, get this, 4:32 to 0:25. Yeah. In case anybody's curious, pmap and pmapall show identical performance in this case. Wow. -Josiah On Tue, Dec 11, 2012 at 1:06 PM, Marshall Bockrath-Vandegrift llas...@gmail.com wrote: Lee Spector lspec...@hampshire.edu writes: If the application does lots of list processing but does so with a mix of Clojure list and sequence manipulation functions, then one would have to write private, list/cons-only versions of all of these things? That is -- overstating it a bit, to be sure, but perhaps not entirely unfairly -- re-implement Clojure's Lisp? I just did a quick look over clojure/core.clj, and `reverse` is the only function which stood out to me as hitting the most pathological case. Every other `conj` loop over a user-provided datastructure is `conj`ing into an explicit non-list/`Cons` type. So I think if you replace your calls to `reverse` and any `conj` loops you have in your own code, you should see a perfectly reasonable speedup. -Marshall -- 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 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
Re: abysmal multicore performance, especially on AMD processors
Marshall: I'm not practiced in recognizing megamorphic call sites, so I could be missing some in the example code below, modified from Lee's original code. It doesn't use reverse or conj, and as far as I can tell doesn't use PersistentList, either, only Cons. (defn burn-cons [size] (let [size (long size)] (loop [i (long 0) value nil] (if (= i size) (last value) (recur (inc i) (clojure.lang.Cons. (* (int i) (+ (float i) (- (int i) (/ (float i) (inc (int i)) value)) (a) invoke (burn-cons 200) sequentially 64 times in a single JVM (b) invoke (burn-cons 200) 64 times using a modified version of pmap that limits the number of active threads to 2 (see below), in a single JVM. I would hope that this would take about half the elapsed time than (a), but the elapsed time is longer than (a) (c) start up two JVMs simultaneously and invoke (burn-cons 200) sequentially 32 times in each. The elapsed time here is less than (a), as I would expect. (Clojure 1.4, Oracle/Apple JDK 1.6.0_37, Mac OS X 10.6.8, running on a machine with Intel core i7 with 4 physical cores but OS X reports it as 8 I think because of 2 hyperthreads per core -- more details available on request). Can you try to reproduce to see if you get similar results? If so, do you know why we get bad parallelism in a single JVM for this code? If there are no megamorphic call sites, then it is examples like this that lead me to wonder about locking in memory allocation and/or GC. With the functions below, my part (b) was measured by doing: (time (doall (nthreads-pmap 2 (burn-cons 200) (unchunk (range 64) Andy (defn unchunk [s] (when (seq s) (lazy-seq (cons (first s) (unchunk (next s)) (defn nthreads-pmap Like pmap, except can take an argument nthreads to control the maximum number of parallel threads used. ([f coll] (let [n (+ 2 (.. Runtime getRuntime availableProcessors))] (nthreads-pmap n f coll))) ([nthreads f coll] (if (= nthreads 1) (map f coll) (let [n (dec nthreads) rets (map #(future (f %)) coll) step (fn step [[x xs :as vs] fs] (lazy-seq (if-let [s (seq fs)] (cons (deref x) (step xs (rest s))) (map deref vs] (step rets (drop n rets) ([nthreads f coll colls] (let [step (fn step [cs] (lazy-seq (let [ss (map seq cs)] (when (every? identity ss) (cons (map first ss) (step (map rest ss)))] (nthreads-pmap nthreads #(apply f %) (step (cons coll colls)) On Dec 11, 2012, at 10:06 AM, Marshall Bockrath-Vandegrift wrote: Lee Spector lspec...@hampshire.edu writes: If the application does lots of list processing but does so with a mix of Clojure list and sequence manipulation functions, then one would have to write private, list/cons-only versions of all of these things? That is -- overstating it a bit, to be sure, but perhaps not entirely unfairly -- re-implement Clojure's Lisp? I just did a quick look over clojure/core.clj, and `reverse` is the only function which stood out to me as hitting the most pathological case. Every other `conj` loop over a user-provided datastructure is `conj`ing into an explicit non-list/`Cons` type. So I think if you replace your calls to `reverse` and any `conj` loops you have in your own code, you should see a perfectly reasonable speedup. -Marshall -- 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 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
Re: when is a zipper better than get-in ?
I just downloaded the sample PDF for FP-OO, and it's delightful; I'll be springing for a copy myself. Russell On Tue, Dec 11, 2012 at 11:14 AM, Brian Marick mar...@exampler.com wrote: On Dec 11, 2012, at 1:04 PM, Brian Marick mar...@exampler.com wrote: If you want to edit trees, using zippers is often much much easier than collection functions. I find the code easier to understand, too. I almost forgot to make a shameless plug for /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo I have a chapter about zippers, with lots of exercises. (I also have a set of exercises in which you implement zippers. It's a nifty data structure.) What the heck: anyone who sends me mail this week can have $5 off. Occasional consulting on programming technique Contract programming in Ruby and Clojure Latest book: /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo -- 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 -- Russell Whitaker http://twitter.com/OrthoNormalRuss / http://orthonormalruss.blogspot.com/ http://www.linkedin.com/pub/russell-whitaker/0/b86/329 -- 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
Re: abysmal multicore performance, especially on AMD processors
...and, suddenly, the high-core-count Opterons show us what we wanted and hoped for. If I increase that range statement to 100 and run it on the 48-core node, it takes 50 seconds (before it took 50 minutes), while the FX-8350 takes 3:31.89 and the 3770K takes 3:48.95. Thanks Marshall! I think you may have just saved us outrageous quantities of time, though Lee isn't convinced that we know exactly what's going on with clojush yet, I don't think. We haven't looked at it yet though I'm sure we will soon enough! On Tue, Dec 11, 2012 at 2:57 PM, Wm. Josiah Erikson wmjos...@gmail.comwrote: And, interestingly enough, suddenly the AMD FX-8350 beats the Intel Core i7 3770K, when before it was very very much not so. So for some reason, this bug was tickled more dramatically on AMD multicore processors than on Intel ones. On Tue, Dec 11, 2012 at 2:54 PM, Wm. Josiah Erikson wmjos...@gmail.comwrote: OK WOW. You hit the nail on the head. It's reverse being called in a pmap that does it. When I redefine my own version of reverse (I totally cheated and just stole this) like this: (defn reverse-recursively [coll] (loop [[r more :as all] (seq coll) acc '()] (if all (recur more (cons r acc)) acc))) I speed it up from, get this, 4:32 to 0:25. Yeah. In case anybody's curious, pmap and pmapall show identical performance in this case. Wow. -Josiah On Tue, Dec 11, 2012 at 1:06 PM, Marshall Bockrath-Vandegrift llas...@gmail.com wrote: Lee Spector lspec...@hampshire.edu writes: If the application does lots of list processing but does so with a mix of Clojure list and sequence manipulation functions, then one would have to write private, list/cons-only versions of all of these things? That is -- overstating it a bit, to be sure, but perhaps not entirely unfairly -- re-implement Clojure's Lisp? I just did a quick look over clojure/core.clj, and `reverse` is the only function which stood out to me as hitting the most pathological case. Every other `conj` loop over a user-provided datastructure is `conj`ing into an explicit non-list/`Cons` type. So I think if you replace your calls to `reverse` and any `conj` loops you have in your own code, you should see a perfectly reasonable speedup. -Marshall -- 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 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
Re: abysmal multicore performance, especially on AMD processors
Hm. Interesting. For the record, the exact code I'm running right now that I'm seeing great parallelism with is this: (defn reverse-recursively [coll] (loop [[r more :as all] (seq coll) acc '()] (if all (recur more (cons r acc)) acc))) (defn burn ([] (loop [i 0 value '()] (if (= i 1) (count (last (take 1 (iterate reverse-recursively value (recur (inc i) (cons (* (int i) (+ (float i) (- (int i) (/ (float i) (inc (int i)) value) ([_] (burn))) (defn pmapall Like pmap but: 1) coll should be finite, 2) the returned sequence will not be lazy, 3) calls to f may occur in any order, to maximize multicore processor utilization, and 4) takes only one coll so far. [f coll] (let [agents (map agent coll)] (dorun (map #(send % f) agents)) (apply await agents) (doall (map deref agents (defn -main [ args] (time ( doall( pmapall burn (range 100 (System/exit 0)) On Tue, Dec 11, 2012 at 3:00 PM, Andy Fingerhut andy.finger...@gmail.comwrote: Marshall: I'm not practiced in recognizing megamorphic call sites, so I could be missing some in the example code below, modified from Lee's original code. It doesn't use reverse or conj, and as far as I can tell doesn't use PersistentList, either, only Cons. (defn burn-cons [size] (let [size (long size)] (loop [i (long 0) value nil] (if (= i size) (last value) (recur (inc i) (clojure.lang.Cons. (* (int i) (+ (float i) (- (int i) (/ (float i) (inc (int i)) value)) (a) invoke (burn-cons 200) sequentially 64 times in a single JVM (b) invoke (burn-cons 200) 64 times using a modified version of pmap that limits the number of active threads to 2 (see below), in a single JVM. I would hope that this would take about half the elapsed time than (a), but the elapsed time is longer than (a) (c) start up two JVMs simultaneously and invoke (burn-cons 200) sequentially 32 times in each. The elapsed time here is less than (a), as I would expect. (Clojure 1.4, Oracle/Apple JDK 1.6.0_37, Mac OS X 10.6.8, running on a machine with Intel core i7 with 4 physical cores but OS X reports it as 8 I think because of 2 hyperthreads per core -- more details available on request). Can you try to reproduce to see if you get similar results? If so, do you know why we get bad parallelism in a single JVM for this code? If there are no megamorphic call sites, then it is examples like this that lead me to wonder about locking in memory allocation and/or GC. With the functions below, my part (b) was measured by doing: (time (doall (nthreads-pmap 2 (burn-cons 200) (unchunk (range 64) Andy (defn unchunk [s] (when (seq s) (lazy-seq (cons (first s) (unchunk (next s)) (defn nthreads-pmap Like pmap, except can take an argument nthreads to control the maximum number of parallel threads used. ([f coll] (let [n (+ 2 (.. Runtime getRuntime availableProcessors))] (nthreads-pmap n f coll))) ([nthreads f coll] (if (= nthreads 1) (map f coll) (let [n (dec nthreads) rets (map #(future (f %)) coll) step (fn step [[x xs :as vs] fs] (lazy-seq (if-let [s (seq fs)] (cons (deref x) (step xs (rest s))) (map deref vs] (step rets (drop n rets) ([nthreads f coll colls] (let [step (fn step [cs] (lazy-seq (let [ss (map seq cs)] (when (every? identity ss) (cons (map first ss) (step (map rest ss)))] (nthreads-pmap nthreads #(apply f %) (step (cons coll colls)) On Dec 11, 2012, at 10:06 AM, Marshall Bockrath-Vandegrift wrote: Lee Spector lspec...@hampshire.edu writes: If the application does lots of list processing but does so with a mix of Clojure list and sequence manipulation functions, then one would have to write private, list/cons-only versions of all of these things? That is -- overstating it a bit, to be sure, but perhaps not entirely unfairly -- re-implement Clojure's Lisp? I just did a quick look over clojure/core.clj, and `reverse` is the only function which stood out to me as hitting the most pathological case. Every other `conj` loop over a user-provided datastructure is `conj`ing into an explicit non-list/`Cons` type. So I think if you replace your calls to `reverse` and any `conj` loops you have in your own
Re: STM - a request for war stories
Just curious, how did you immediately eliminate the possibility that the reducing function was mutating the list that is being reduced? No concurrency involved. In regular Java the 95% leading cause of CME is precisely that. Anyway, this applies to immutable structures per se, whether combined with atoms, refs, or none. But a full wartime story must also cover how the solution avoids the pitfalls of retryable transactions. This is the real sore point in my experience, and the one which makes STM an all-or-nothing enterprise. On Tuesday, December 11, 2012 8:53:40 PM UTC+1, stuart@gmail.com wrote: Hi Paul, Here is a real-world, production software example of the advantage of values+refs over mutable objects and locks. A Datomic user reported the following stack trace as a potential bug: 12:45:43.480 [qtp517338136-84] WARN c.v.a.s.p.e.UnknownExceptionHandler - UnknownExceptionHandler: null java.util.ConcurrentModificationException: null at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819) ~[na:1.7.0_07] at java.util.ArrayList$Itr.next(ArrayList.java:791) ~[na:1.7.0_07] at clojure.core.protocols$fn__5871.invoke(protocols.clj:76) ~[clojure-1.4.0.jar:na] at clojure.core.protocols$fn__5828$G__5823__5841.invoke(protocols.clj:13) ~[clojure-1.4.0.jar:na] at clojure.core$reduce.invoke(core.clj:6030) ~[clojure-1.4.0.jar:na] I immediately had 99% confidence that the bug was in user code, and even a pretty good idea what went wrong. A call to reduce is a functional transformation, and it expects to be passed values. The exception clearly indicates a violation of that contract, and is caused by cross-thread aliasing and mutation in the calling code. Regards, Stu -- 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
Re: STM - a request for war stories
I want to +1 what Stuart said. In my research on the subject, almost every implementation of STM that allows for mutable-by-default data has ended up as a miserable failure. Specifically see the results from Microsoft's research: http://www.infoq.com/news/2010/05/STM-Dropped Clojure's implementation of STM hinges on the fact that must data is immutable. Thus a transaction that reads 100 items from one ref and writes the results to two other refs, needs only track updates to 3 pointers instead of 103. The PyPy STM model is a bit different ( http://morepypy.blogspot.com/2012/05/stm-update-back-to-threads.html). Here they assume that all threads are serial (global lock) and then selectively enable STM in places where it is known that threads are unlikely to clobber each other's data. It has resulted in slight success, but that's mostly due to the fact that Python currently is locked to a single core, so any concurrency is better than nothing in that regard. That being said, the PyPy guys have a 10+ year history of proving scoffers wrong, so there's hope. So as Stuart said, it's worth pointing out that in a OO mutable-by-default language, STM is basically worthless. Timothy Baldridge On Tue, Dec 11, 2012 at 1:30 PM, Marko Topolnik marko.topol...@gmail.comwrote: Just curious, how did you immediately eliminate the possibility that the reducing function was mutating the list that is being reduced? No concurrency involved. In regular Java the 95% leading cause of CME is precisely that. Anyway, this applies to immutable structures per se, whether combined with atoms, refs, or none. But a full wartime story must also cover how the solution avoids the pitfalls of retryable transactions. This is the real sore point in my experience, and the one which makes STM an all-or-nothing enterprise. On Tuesday, December 11, 2012 8:53:40 PM UTC+1, stuart@gmail.comwrote: Hi Paul, Here is a real-world, production software example of the advantage of values+refs over mutable objects and locks. A Datomic user reported the following stack trace as a potential bug: 12:45:43.480 [qtp517338136-84] WARN c.v.a.s.p.e.UnknownExceptionH**andler - UnknownExceptionHandler: null java.util.ConcurrentModificati**onException: null at java.util.ArrayList$Itr.checkF**orComodification(ArrayList.**java:819) ~[na:1.7.0_07] at java.util.ArrayList$Itr.next(A**rrayList.java:791) ~[na:1.7.0_07] at clojure.core.protocols$fn_**_5871.invoke(protocols.clj:76) ~[clojure-1.4.0.jar:na] at clojure.core.protocols$fn_**_5828$G__5823__5841.invoke(pro**tocols.clj:13) ~[clojure-1.4.0.jar:na] at clojure.core$reduce.invoke(cor**e.clj:6030) ~[clojure-1.4.0.jar:na] I immediately had 99% confidence that the bug was in user code, and even a pretty good idea what went wrong. A call to reduce is a functional transformation, and it expects to be passed values. The exception clearly indicates a violation of that contract, and is caused by cross-thread aliasing and mutation in the calling code. Regards, Stu -- 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 -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to 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
why is nth called here?
i am trying to solve euler problem 125. when i tested this code: (ns euler.Problem125) (defn is-palindrome [n] (let [s (str n)] (= (seq s) (reverse s (defn to-check [] (filter is-palindrome (range 1 1000))) (defn square-root [n] (Math/sqrt n)) (defn squared [n] (* n n)) (defn try-find-sequence [n] (loop [start-at (int (square-root n))] (let [combinator (fn [[sum smallest] element] [(+ sum element) (dec element)]) reduced (reduce combinator [0 start-at] (range start-at 0 -1)) pred (fn [[sum smallest]] ( sum n)) until-match-or-overflow (take-while pred reduced) solution-or-not (last until-match-or-overflow)] (cond (= (first solution-or-not) n) nil (= (first solution-or-not) n) (second solution-or-not) :else (recur (dec start-at)) (println (try-find-sequence 595)) i get: Exception in thread main java.lang.UnsupportedOperationException: nth not supported on this type: Long at clojure.lang.RT.nthFrom(RT.java:846) at clojure.lang.RT.nth(RT.java:796) at euler.Problem125$try_find_sequence$pred__16.invoke(Problem125.clj:20) at clojure.core$take_while$fn__4116.invoke(core.clj:2512) but why? i don't call nth on anything! -- 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
Re: why is nth called here?
nth is called in doing the destructuring for the argument lists in your fns defined in try-find-sequence. On Tue, Dec 11, 2012 at 1:20 PM, Dennis Haupt d.haup...@gmail.com wrote: i am trying to solve euler problem 125. when i tested this code: (ns euler.Problem125) (defn is-palindrome [n] (let [s (str n)] (= (seq s) (reverse s (defn to-check [] (filter is-palindrome (range 1 1000))) (defn square-root [n] (Math/sqrt n)) (defn squared [n] (* n n)) (defn try-find-sequence [n] (loop [start-at (int (square-root n))] (let [combinator (fn [[sum smallest] element] [(+ sum element) (dec element)]) reduced (reduce combinator [0 start-at] (range start-at 0 -1)) pred (fn [[sum smallest]] ( sum n)) until-match-or-overflow (take-while pred reduced) solution-or-not (last until-match-or-overflow)] (cond (= (first solution-or-not) n) nil (= (first solution-or-not) n) (second solution-or-not) :else (recur (dec start-at)) (println (try-find-sequence 595)) i get: Exception in thread main java.lang.UnsupportedOperationException: nth not supported on this type: Long at clojure.lang.RT.nthFrom(RT.java:846) at clojure.lang.RT.nth(RT.java:796) at euler.Problem125$try_find_sequence$pred__16.invoke(Problem125.clj:20) at clojure.core$take_while$fn__4116.invoke(core.clj:2512) but why? i don't call nth on anything! -- 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 -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- 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
Re: why is nth called here?
i just saw my error :/ Am 11.12.2012 22:22, schrieb Ben Wolfson: nth is called in doing the destructuring for the argument lists in your fns defined in try-find-sequence. On Tue, Dec 11, 2012 at 1:20 PM, Dennis Haupt d.haup...@gmail.com wrote: i am trying to solve euler problem 125. when i tested this code: (ns euler.Problem125) (defn is-palindrome [n] (let [s (str n)] (= (seq s) (reverse s (defn to-check [] (filter is-palindrome (range 1 1000))) (defn square-root [n] (Math/sqrt n)) (defn squared [n] (* n n)) (defn try-find-sequence [n] (loop [start-at (int (square-root n))] (let [combinator (fn [[sum smallest] element] [(+ sum element) (dec element)]) reduced (reduce combinator [0 start-at] (range start-at 0 -1)) pred (fn [[sum smallest]] ( sum n)) until-match-or-overflow (take-while pred reduced) solution-or-not (last until-match-or-overflow)] (cond (= (first solution-or-not) n) nil (= (first solution-or-not) n) (second solution-or-not) :else (recur (dec start-at)) (println (try-find-sequence 595)) i get: Exception in thread main java.lang.UnsupportedOperationException: nth not supported on this type: Long at clojure.lang.RT.nthFrom(RT.java:846) at clojure.lang.RT.nth(RT.java:796) at euler.Problem125$try_find_sequence$pred__16.invoke(Problem125.clj:20) at clojure.core$take_while$fn__4116.invoke(core.clj:2512) but why? i don't call nth on anything! -- 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 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
Re: STM - a request for war stories
Is it possible to write a reducing function that mutates a list in Clojure? Sure. But I think it is absurdly unlikely that it would happen by accident. My 1% chance wasn't hedging against that case -- I was hedging against a bug in reduce itself. I don't really see even a 1% likelihood of either of those, but I played DD as a kid and learned that even the most unlikely things happen one time in twenty. :-) Stu On Tue, Dec 11, 2012 at 3:30 PM, Marko Topolnik marko.topol...@gmail.comwrote: Just curious, how did you immediately eliminate the possibility that the reducing function was mutating the list that is being reduced? No concurrency involved. In regular Java the 95% leading cause of CME is precisely that. Anyway, this applies to immutable structures per se, whether combined with atoms, refs, or none. But a full wartime story must also cover how the solution avoids the pitfalls of retryable transactions. This is the real sore point in my experience, and the one which makes STM an all-or-nothing enterprise. On Tuesday, December 11, 2012 8:53:40 PM UTC+1, stuart@gmail.comwrote: Hi Paul, Here is a real-world, production software example of the advantage of values+refs over mutable objects and locks. A Datomic user reported the following stack trace as a potential bug: 12:45:43.480 [qtp517338136-84] WARN c.v.a.s.p.e.UnknownExceptionH**andler - UnknownExceptionHandler: null java.util.ConcurrentModificati**onException: null at java.util.ArrayList$Itr.checkF**orComodification(ArrayList.**java:819) ~[na:1.7.0_07] at java.util.ArrayList$Itr.next(A**rrayList.java:791) ~[na:1.7.0_07] at clojure.core.protocols$fn_**_5871.invoke(protocols.clj:76) ~[clojure-1.4.0.jar:na] at clojure.core.protocols$fn_**_5828$G__5823__5841.invoke(pro**tocols.clj:13) ~[clojure-1.4.0.jar:na] at clojure.core$reduce.invoke(cor**e.clj:6030) ~[clojure-1.4.0.jar:na] I immediately had 99% confidence that the bug was in user code, and even a pretty good idea what went wrong. A call to reduce is a functional transformation, and it expects to be passed values. The exception clearly indicates a violation of that contract, and is caused by cross-thread aliasing and mutation in the calling code. Regards, Stu -- 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 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
Re: core.logic vs. Prolog
There's not a list of features so much as a list of improvements I would like to make. Some medium to big project ideas: - CLP(Set) - Improvements to tabling (currently a lot of redundant information is recorded) - Negation (based on CiaoProlog work) - Environment Trimming (to make the Definite Clause Grammar feature much more efficient) Not sure when I'll get to these - there is a considerable amount of interesting optimization work to be done on the current CLP(FD) implementation and surrounding CLP infrastructure. If there's some Prolog feature / predicate you'd like to see bring it up and it will be considered. David On Tue, Dec 11, 2012 at 1:56 PM, JvJ kfjwhee...@gmail.com wrote: Is there a list of features that you'd like to implement that core.logic doesn't have yet? On Tuesday, 11 December 2012 00:52:24 UTC-5, David Nolen wrote: core.logic is still pretty young - some (many?) Prolog niceties may not be present. Don't know until you try ;) On Tue, Dec 11, 2012 at 12:29 AM, JvJ kfjwh...@gmail.com wrote: I have some code that uses Prolog, but I want to get rid of the native dependencies inherent in SWI Prolog/JPL. If I were to switch to core.logic, what would I lose and what would I gain? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@**googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en -- 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 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
Re: when is a zipper better than get-in ?
Brian, Thanks! I bought and started reading your book. Seems excellent so far, and wanted to say that I particularly appreciate your stated willingness to help those of us with no experience in functional programming. Nando On Dec 11, 2012, at 20:14, Brian Marick mar...@exampler.com wrote: On Dec 11, 2012, at 1:04 PM, Brian Marick mar...@exampler.com wrote: If you want to edit trees, using zippers is often much much easier than collection functions. I find the code easier to understand, too. I almost forgot to make a shameless plug for /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo I have a chapter about zippers, with lots of exercises. (I also have a set of exercises in which you implement zippers. It's a nifty data structure.) What the heck: anyone who sends me mail this week can have $5 off. Occasional consulting on programming technique Contract programming in Ruby and Clojure Latest book: /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo -- 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 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
Re: core.logic vs. Prolog
Oh and of course AND and OR parallelism. On Tue, Dec 11, 2012 at 5:44 PM, David Nolen dnolen.li...@gmail.com wrote: There's not a list of features so much as a list of improvements I would like to make. Some medium to big project ideas: - CLP(Set) - Improvements to tabling (currently a lot of redundant information is recorded) - Negation (based on CiaoProlog work) - Environment Trimming (to make the Definite Clause Grammar feature much more efficient) Not sure when I'll get to these - there is a considerable amount of interesting optimization work to be done on the current CLP(FD) implementation and surrounding CLP infrastructure. If there's some Prolog feature / predicate you'd like to see bring it up and it will be considered. David On Tue, Dec 11, 2012 at 1:56 PM, JvJ kfjwhee...@gmail.com wrote: Is there a list of features that you'd like to implement that core.logic doesn't have yet? On Tuesday, 11 December 2012 00:52:24 UTC-5, David Nolen wrote: core.logic is still pretty young - some (many?) Prolog niceties may not be present. Don't know until you try ;) On Tue, Dec 11, 2012 at 12:29 AM, JvJ kfjwh...@gmail.com wrote: I have some code that uses Prolog, but I want to get rid of the native dependencies inherent in SWI Prolog/JPL. If I were to switch to core.logic, what would I lose and what would I gain? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@**googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en -- 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 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
Re: when is a zipper better than get-in ?
On Dec 11, 2012, at 4:45 PM, Nando d.na...@gmail.com wrote: Thanks! I bought and started reading your book. Seems excellent so far, and wanted to say that I particularly appreciate your stated willingness to help those of us with no experience in functional programming. I'm pleased to hear that. Occasional consulting on programming technique Contract programming in Ruby and Clojure Latest book: /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo -- 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
Re: Meaning of =
On Tue, Dec 11, 2012 at 5:17 AM, Jim foo.bar jimpil1...@gmail.com wrote: I disagree... One of the nice things about clojrue is that, at tis hear, lies the 'equiv' operator which is basically the 'egal' fn as defined by Baker [1993] [Equal rights for functional objects or the mroe things change the more they stay the same]. When using '=' with data-structures you are essentially comparing values and not types. To come back to your example, both are sequential seqs that contain the same values in the same order. Why shouldn't they be equal? It's interesting that you quote Baker, because this is one of the places where Clojure explicitly cheats and ignores Baker's operational equivalence in favour of convenience. Egal's operational equivalence would not treat lists and vectors as equivalent because they have very different behaviour characteristics when it comes to conj, etc, but if Clojure treated them differently then laziness would be much more burdensome. There are a few other places where Clojure cheats too, but this is the most noticeable. -Phil -- 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
Re: Meaning of =
one of the things which seem to be true but nowhere completely successfully fleshed out is the fact that equality is very subjective. there can and should be many different ways to pose and answer the question a == b. -- 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
Re: Slime and heroku setup question
On Tue, Dec 11, 2012 at 11:07 AM, Jonathon McKitrick jmckitr...@gmail.com wrote: I sort of got clojure interactively running and working with slime. I'd like to interactively run and test in emacs, then push to heroku. Any tutorials or pointers on how to do this? For what it's worth direct socket access is unsupported and will probably break in the future; communication with Heroku dynos is supposed to only happen through the HTTP router. I have an article on using nREPL's HTTP transport to connect to a live dyno, (https://devcenter.heroku.com/articles/debugging-clojure) but unfortunately client-side support for the HTTP transport hasn't been implemented in nrepl.el yet, so you have to use inferior-lisp with `lein repl :connect ...`. The tricky thing here with remote development is that all your :require calls will hit the disk by default, which means that any changes you make to a namespace using region-centric commands (which don't hit the disk) will be overridden the first time they're :required or if they are ever reloaded. I don't have a good solution; you would probably have to modify nrepl.el to prefer the local copy of all files; even that would be difficult without wall-hacking an equivalent of CL's provide function to trick :require into thinking a namespace had already been loaded. I think Laurent Petit was working on addressing this issue in another thread? Anyway, it's possible and would be really cool, but it would also be a lot of work, most of it in elisp. -Phil -- 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
Re: Meaning of =
On Tue, Dec 11, 2012 at 3:32 PM, Raoul Duke rao...@gmail.com wrote: one of the things which seem to be true but nowhere completely successfully fleshed out is the fact that equality is very subjective. there can and should be many different ways to pose and answer the question a == b. There is a very good explanation of an objective equality predicate in Henry Baker's Equal Rights for Functional Objects paper: http://home.pipeline.com/~hbaker1/ObjectIdentity.html Anyone interested in equality, FP, or why CL and Elisp are so annoying to work with should read this paper. Keep in mind that Clojure cheats in a few places in the name of convenience and doesn't quite implement what he's described though. -Phil -- 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
Re: Meaning of =
Hi, Equality is never subjective. There maybe different equality relations defined. In most cases (integer) one os well served by intuition. In other cases (clojure's =) the definition may not be intuitive, but never subjective. On Dec 12, 2012 12:32 AM, Raoul Duke rao...@gmail.com wrote: one of the things which seem to be true but nowhere completely successfully fleshed out is the fact that equality is very subjective. there can and should be many different ways to pose and answer the question a == b. -- 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 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
Re: Meaning of =
Great paper btw! On Dec 12, 2012 12:42 AM, Phil Hagelberg p...@hagelb.org wrote: On Tue, Dec 11, 2012 at 3:32 PM, Raoul Duke rao...@gmail.com wrote: one of the things which seem to be true but nowhere completely successfully fleshed out is the fact that equality is very subjective. there can and should be many different ways to pose and answer the question a == b. There is a very good explanation of an objective equality predicate in Henry Baker's Equal Rights for Functional Objects paper: http://home.pipeline.com/~hbaker1/ObjectIdentity.html Anyone interested in equality, FP, or why CL and Elisp are so annoying to work with should read this paper. Keep in mind that Clojure cheats in a few places in the name of convenience and doesn't quite implement what he's described though. -Phil -- 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 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
Re: Meaning of =
Equality is never subjective. There maybe different equality relations defined. In most cases (integer) one os well served by intuition. In other cases (clojure's =) the definition may not be intuitive, but never subjective. ok sheesh then ^subjective^context dependent -- 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
Re: Meaning of =
On Dec 11, 2012, at 5:42 PM, Phil Hagelberg p...@hagelb.org wrote: Henry Baker's Equal Rights for Functional Objects paper: http://home.pipeline.com/~hbaker1/ObjectIdentity.html Henry Baker was/is a brilliantly just-outside-of-the-box thinker. Many of the papers at http://home.pipeline.com/~hbaker1 are well worth reading. They're not as cohesive or as brilliant as the Lambda papers http://library.readscheme.org/page1.html but that's an awfully high bar. Occasional consulting on programming technique Contract programming in Ruby and Clojure Latest book: /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo -- 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
Re: abysmal multicore performance, especially on AMD processors
On Dec 11, 2012, at 1:06 PM, Marshall Bockrath-Vandegrift wrote: So I think if you replace your calls to `reverse` and any `conj` loops you have in your own code, you should see a perfectly reasonable speedup. Tantalizing, but on investigation I see that our real application actually does very little explicitly with reverse or conj, and I don't actually think that we're getting reasonable speedups (which is what led me to try that benchmark). So while I'm not sure of the source of the problem in our application I think there can be a problem even if one avoids direct calls to reverse and conj. Andy's recent tests also seem to confirm this. BTW benchmarking our real application (https://github.com/lspector/Clojush) is a bit tricky because it's riddled with random number generator calls that can have big effects, but we're going to look into working around that. Recent postings re: seedable RNGs may help, although changing all of the RNG code may be a little involved because we use thread-local RNGs (to avoid contention and get good multicore speedups... we thought!). -Lee -- 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
Re: Slime and heroku setup question
Well, I've used slime with SBCL for quite a while, but this is my first foray into clojure and heroku. Are you basically saying the best approach is just to edit locally, push to heroku, and run? There's really no way to have a similar environment set up locally that runs as well? I haven't gotten to the point of connecting to dynos or running the repl on heroku just yet. On Tuesday, December 11, 2012 6:39:43 PM UTC-5, Phil Hagelberg wrote: On Tue, Dec 11, 2012 at 11:07 AM, Jonathon McKitrick jmcki...@gmail.com javascript: wrote: I sort of got clojure interactively running and working with slime. I'd like to interactively run and test in emacs, then push to heroku. Any tutorials or pointers on how to do this? For what it's worth direct socket access is unsupported and will probably break in the future; communication with Heroku dynos is supposed to only happen through the HTTP router. I have an article on using nREPL's HTTP transport to connect to a live dyno, (https://devcenter.heroku.com/articles/debugging-clojure) but unfortunately client-side support for the HTTP transport hasn't been implemented in nrepl.el yet, so you have to use inferior-lisp with `lein repl :connect ...`. The tricky thing here with remote development is that all your :require calls will hit the disk by default, which means that any changes you make to a namespace using region-centric commands (which don't hit the disk) will be overridden the first time they're :required or if they are ever reloaded. I don't have a good solution; you would probably have to modify nrepl.el to prefer the local copy of all files; even that would be difficult without wall-hacking an equivalent of CL's provide function to trick :require into thinking a namespace had already been loaded. I think Laurent Petit was working on addressing this issue in another thread? Anyway, it's possible and would be really cool, but it would also be a lot of work, most of it in elisp. -Phil -- 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
Re: core.logic vs. Prolog
Thanks. I can't think of a feature at the moment. I'm just trying to decide between the two. I'm working on a rule engine/DSL for game AI and I'm trying to make a decision... but I still haven't worked out all the requirements. On Tuesday, 11 December 2012 17:45:40 UTC-5, David Nolen wrote: Oh and of course AND and OR parallelism. On Tue, Dec 11, 2012 at 5:44 PM, David Nolen dnolen...@gmail.comjavascript: wrote: There's not a list of features so much as a list of improvements I would like to make. Some medium to big project ideas: - CLP(Set) - Improvements to tabling (currently a lot of redundant information is recorded) - Negation (based on CiaoProlog work) - Environment Trimming (to make the Definite Clause Grammar feature much more efficient) Not sure when I'll get to these - there is a considerable amount of interesting optimization work to be done on the current CLP(FD) implementation and surrounding CLP infrastructure. If there's some Prolog feature / predicate you'd like to see bring it up and it will be considered. David On Tue, Dec 11, 2012 at 1:56 PM, JvJ kfjwh...@gmail.com javascript:wrote: Is there a list of features that you'd like to implement that core.logic doesn't have yet? On Tuesday, 11 December 2012 00:52:24 UTC-5, David Nolen wrote: core.logic is still pretty young - some (many?) Prolog niceties may not be present. Don't know until you try ;) On Tue, Dec 11, 2012 at 12:29 AM, JvJ kfjwh...@gmail.com wrote: I have some code that uses Prolog, but I want to get rid of the native dependencies inherent in SWI Prolog/JPL. If I were to switch to core.logic, what would I lose and what would I gain? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@**googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: 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 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
Re: Slime and heroku setup question
On Tue, Dec 11, 2012 at 6:55 PM, Jonathon McKitrick jmckitr...@gmail.com wrote: Well, I've used slime with SBCL for quite a while, but this is my first foray into clojure and heroku. Are you basically saying the best approach is just to edit locally, push to heroku, and run? I suppose if you ensure everything gets required when you boot your app and you limit yourself to commands which operate on the region rather than loading from disk (and avoid reloads) then you should be fine. It's just easy to get into an inconsistent state between what's on disk locally and what's in memory during any repl-driven development; throwing in a third factor of the remote disk just adds more room for error. -Phil -- 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
Re: STM - a request for war stories
Yes, upon second thought I saw exactly what you mean. I think you make an important point: when talking about the STM we need to look at the wider picture. Where a mutable-by-default language needs the STM, Clojure gets by with just atoms because a single swap! call can do any number of mutations at once. We naturally tend to design things so that everything related fits into a single structure and the result simply doesn't need the STM. Therefore the threshold of complexity beyond which you need an STM solution in Clojure is quite a bit higher than usual. An important angle to my experience with Clojure that I now see must be added is that I never got frustrated with Clojure's STM because it failed to deliver: I just found that my solutions worked perfectly well without it. On Tuesday, December 11, 2012 10:53:08 PM UTC+1, stuart@gmail.com wrote: Is it possible to write a reducing function that mutates a list in Clojure? Sure. But I think it is absurdly unlikely that it would happen by accident. My 1% chance wasn't hedging against that case -- I was hedging against a bug in reduce itself. I don't really see even a 1% likelihood of either of those, but I played DD as a kid and learned that even the most unlikely things happen one time in twenty. :-) Stu On Tue, Dec 11, 2012 at 3:30 PM, Marko Topolnik marko.t...@gmail.comjavascript: wrote: Just curious, how did you immediately eliminate the possibility that the reducing function was mutating the list that is being reduced? No concurrency involved. In regular Java the 95% leading cause of CME is precisely that. Anyway, this applies to immutable structures per se, whether combined with atoms, refs, or none. But a full wartime story must also cover how the solution avoids the pitfalls of retryable transactions. This is the real sore point in my experience, and the one which makes STM an all-or-nothing enterprise. On Tuesday, December 11, 2012 8:53:40 PM UTC+1, stuart@gmail.comwrote: Hi Paul, Here is a real-world, production software example of the advantage of values+refs over mutable objects and locks. A Datomic user reported the following stack trace as a potential bug: 12:45:43.480 [qtp517338136-84] WARN c.v.a.s.p.e.UnknownExceptionH**andler - UnknownExceptionHandler: null java.util.ConcurrentModificati**onException: null at java.util.ArrayList$Itr.checkF**orComodification(ArrayList.**java:819) ~[na:1.7.0_07] at java.util.ArrayList$Itr.next(A**rrayList.java:791) ~[na:1.7.0_07] at clojure.core.protocols$fn_**_5871.invoke(protocols.clj:76) ~[clojure-1.4.0.jar:na] at clojure.core.protocols$fn_**_5828$G__5823__5841.invoke(pro**tocols.clj:13) ~[clojure-1.4.0.jar:na] at clojure.core$reduce.invoke(cor**e.clj:6030) ~[clojure-1.4.0.jar:na] I immediately had 99% confidence that the bug was in user code, and even a pretty good idea what went wrong. A call to reduce is a functional transformation, and it expects to be passed values. The exception clearly indicates a violation of that contract, and is caused by cross-thread aliasing and mutation in the calling code. Regards, Stu -- 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