misuse of or bug in transients?
When I convert the following code to use transients it returns different result. Am I doing anything wrong or is it a bug in transients? (defn tt [] (loop [i 0 tset #{}] (if (= i (int 5e5)) (count tset) (recur (inc i) (let [nn (rem (* i (int 1e3)) 131071) plus (count (filter #(contains? tset %) (range nn (+ nn 10 ] (conj tset (+ plus nn))) (tt) 131074 (defn tt [] (loop [i 0 tset (transient #{})] (if (= i (int 5e5)) (count (persistent! tset)) (recur (inc i) (let [nn (rem (* i (int 1e3)) 131071) plus (count (filter #(contains? tset %) (range nn (+ nn 10 ] (conj! tset (+ plus nn))) (tt) 131071 P.S. Tested under 1.3-RC0 and 1.2.1 -- 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: misuse of or bug in transients?
Certainly looks like a valid use of transients. Might be related to http://dev.clojure.org/jira/browse/CLJ-829 but I dunno. On Sep 16, 9:55 am, Sergey Didenko sergey.dide...@gmail.com wrote: When I convert the following code to use transients it returns different result. Am I doing anything wrong or is it a bug in transients? (defn tt [] (loop [i 0 tset #{}] (if (= i (int 5e5)) (count tset) (recur (inc i) (let [nn (rem (* i (int 1e3)) 131071) plus (count (filter #(contains? tset %) (range nn (+ nn 10 ] (conj tset (+ plus nn))) (tt) 131074 (defn tt [] (loop [i 0 tset (transient #{})] (if (= i (int 5e5)) (count (persistent! tset)) (recur (inc i) (let [nn (rem (* i (int 1e3)) 131071) plus (count (filter #(contains? tset %) (range nn (+ nn 10 ] (conj! tset (+ plus nn))) (tt) 131071 P.S. Tested under 1.3-RC0 and 1.2.1 -- 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: misuse of or bug in transients?
Here's what I speculate the problem is: Last time I checked, contains? doesn't work on transient sets. Try rewriting (contains? tset %) as (tset %). Let me know if that change fixes your program. This is a bug I reported something like 1-2 years ago. If this turns out to be the source of your problem, I'm disappointed to hear it is still not fixed in 1.3. --Mark On Fri, Sep 16, 2011 at 10:53 AM, Alan Malloy a...@malloys.org wrote: Certainly looks like a valid use of transients. Might be related to http://dev.clojure.org/jira/browse/CLJ-829 but I dunno. On Sep 16, 9:55 am, Sergey Didenko sergey.dide...@gmail.com wrote: When I convert the following code to use transients it returns different result. Am I doing anything wrong or is it a bug in transients? (defn tt [] (loop [i 0 tset #{}] (if (= i (int 5e5)) (count tset) (recur (inc i) (let [nn (rem (* i (int 1e3)) 131071) plus (count (filter #(contains? tset %) (range nn (+ nn 10 ] (conj tset (+ plus nn))) (tt) 131074 (defn tt [] (loop [i 0 tset (transient #{})] (if (= i (int 5e5)) (count (persistent! tset)) (recur (inc i) (let [nn (rem (* i (int 1e3)) 131071) plus (count (filter #(contains? tset %) (range nn (+ nn 10 ] (conj! tset (+ plus nn))) (tt) 131071 P.S. Tested under 1.3-RC0 and 1.2.1 -- 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: misuse of or bug in transients?
On Fri, Sep 16, 2011 at 2:07 PM, Mark Engelberg mark.engelb...@gmail.comwrote: Here's what I speculate the problem is: Last time I checked, contains? doesn't work on transient sets. Try rewriting (contains? tset %) as (tset %). Let me know if that change fixes your program. This is a bug I reported something like 1-2 years ago. If this turns out to be the source of your problem, I'm disappointed to hear it is still not fixed in 1.3. --Mark Examining the Java sources it looks like the transient collections do not support contains? by design. David -- 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: misuse of or bug in transients?
Then it is contrary to the docs: http://clojure.org/transients Transients support the read-only interface of the source, i.e. you can call nth, get, count and fn-call a transient vector, just like a persistent vector. Examining the Java sources it looks like the transient collections do not support contains? by design. -- 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: misuse of or bug in transients?
Yes, now it works. Thanks. Try rewriting (contains? tset %) as (tset %). Let me know if that change fixes your program. -- 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: misuse of or bug in transients?
On Fri, Sep 16, 2011 at 2:20 PM, David Nolen dnolen.li...@gmail.com wrote: On Fri, Sep 16, 2011 at 2:07 PM, Mark Engelberg mark.engelb...@gmail.comwrote: Here's what I speculate the problem is: Last time I checked, contains? doesn't work on transient sets. Try rewriting (contains? tset %) as (tset %). Let me know if that change fixes your program. This is a bug I reported something like 1-2 years ago. If this turns out to be the source of your problem, I'm disappointed to hear it is still not fixed in 1.3. --Mark Examining the Java sources it looks like the transient collections do not support contains? by design. Am I misunderstanding https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ATransientSet.java#L32 ? -- 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: misuse of or bug in transients?
On Fri, Sep 16, 2011 at 11:20 AM, David Nolen dnolen.li...@gmail.comwrote: Examining the Java sources it looks like the transient collections do not support contains? by design. David Unfortunately, another design decision in Clojure is that contains? returns spurious results, rather than an error, for things that do not support contains?. As a consequence, when you try to use contains? with transient sets (a perfectly reasonable thing to assume would work), you get zero feedback that this is unsupported -- your program just returns incorrect results. --Mark -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: misuse of or bug in transients?
On Fri, Sep 16, 2011 at 2:37 PM, Aaron Cohen aa...@assonance.org wrote: Am I misunderstanding https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ATransientSet.java#L32 ? Transient collections don't implement Associative (which extends IPersistentCollection and ILookup) which defines containsKey. I do see that ITransientAssociative does exist, but it does not define containsKey. David -- 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: misuse of or bug in transients?
On Fri, Sep 16, 2011 at 2:44 PM, Mark Engelberg mark.engelb...@gmail.comwrote: On Fri, Sep 16, 2011 at 11:20 AM, David Nolen dnolen.li...@gmail.comwrote: Examining the Java sources it looks like the transient collections do not support contains? by design. David Unfortunately, another design decision in Clojure is that contains? returns spurious results, rather than an error, for things that do not support contains?. As a consequence, when you try to use contains? with transient sets (a perfectly reasonable thing to assume would work), you get zero feedback that this is unsupported -- your program just returns incorrect results. --Mark Hmm... contains? doesn't throw when given a type that it doesn't support it. But then neither does get. One problem I see is that you can't map over a heterogenous collection with these fns if it does throw without enumerating the various types that are supported everywhere in your code. Protocols in ClojureScript, where they appear much earlier and can be properly extended to set of desired types (unlike Java interfaces), provide a better story here. David -- 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: misuse of or bug in transients?
Here is the (a?) ticket for this issue: http://dev.clojure.org/jira/browse/CLJ-700 I too have thought, it was fixed by now. Am Freitag, 16. September 2011 schrieb David Nolen : On Fri, Sep 16, 2011 at 2:37 PM, Aaron Cohen aa...@assonance.orgjavascript:_e({}, 'cvml', 'aa...@assonance.org'); wrote: Am I misunderstanding https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ATransientSet.java#L32 ? Transient collections don't implement Associative (which extends IPersistentCollection and ILookup) which defines containsKey. I do see that ITransientAssociative does exist, but it does not define containsKey. David -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.comjavascript:_e({}, 'cvml', '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 javascript:_e({}, 'cvml', 'clojure%2bunsubscr...@googlegroups.com'); For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- __ Herwig Hochleitner -- 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: misuse of or bug in transients?
On Fri, Sep 16, 2011 at 3:26 PM, Herwig Hochleitner hhochleit...@gmail.comwrote: Here is the (a?) ticket for this issue: http://dev.clojure.org/jira/browse/CLJ-700 I too have thought, it was fixed by now. The other thing to consider is that - is this a contract that is desirable to support? Transients are only about performance - lowering the time it takes to construct a collection. Perhaps there are faster implementations which cannot fulfill the contract of supporting contains? David -- 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: misuse of or bug in transients?
Support of membership testing is pretty much the defining characteristic of sets, transient or not. Transient sets already support membership testing in the form of (my-set item). If they support the IFn interface for membership testing, it's hard for me to imagine that it would be much more difficult to support the same behavior for whatever interface makes contains? work properly. On Fri, Sep 16, 2011 at 12:42 PM, David Nolen dnolen.li...@gmail.comwrote: On Fri, Sep 16, 2011 at 3:26 PM, Herwig Hochleitner hhochleit...@gmail.com wrote: Here is the (a?) ticket for this issue: http://dev.clojure.org/jira/browse/CLJ-700 I too have thought, it was fixed by now. The other thing to consider is that - is this a contract that is desirable to support? Transients are only about performance - lowering the time it takes to construct a collection. Perhaps there are faster implementations which cannot fulfill the contract of supporting contains? David -- 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: misuse of or bug in transients?
Am Freitag, 16. September 2011 schrieb David Nolen : The other thing to consider is that - is this a contract that is desirable to support? Transients are only about performance - lowering the time it takes to construct a collection. Perhaps there are faster implementations which cannot fulfill the contract of supporting contains? Fair point! OTOH such an implementation would still need to support get, which is supposed to be fast too (the reason it's stated explicitely in the contains? doc is, so that people don't confuse it with some) In fact, one could implement contains? as (defn contains? [c x] (not= ::not-found (get c x ::not-found))) right now and retain the performance guarantees. And it would work on transients too :) kind regards -- __ Herwig Hochleitner -- 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: misuse of or bug in transients?
On Fri, Sep 16, 2011 at 4:33 PM, Mark Engelberg mark.engelb...@gmail.comwrote: Support of membership testing is pretty much the defining characteristic of sets, transient or not. Transient sets already support membership testing in the form of (my-set item). If they support the IFn interface for membership testing, it's hard for me to imagine that it would be much more difficult to support the same behavior for whatever interface makes contains? work properly. I suspect that part of the reason there is little movement on this is that transients are as of 1.3 *still* marked alpha. And from what I understand they will most likely become an implementation detail. That is direct use will be thoroughly discouraged. David -- 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: misuse of or bug in transients?
Sorry! Disregard my former post. In fact, get doesn't work on transients either. Fingers too fast :/ Still, looking keys up in a map while building it, is a valid use case for transients, because you do that with persistent collections too. Same with sets. At the very least, get and contains? should throw on transients, but as Mark said: Lookup is the defining characteristic of sets and maps. If transients support the read-only interface of their persistent variants, why shouldn't they support generic access too? IIRC you're supposed to convert existing reduce's and loop's by wrapping it in (persistent! ... (transient ...)) and replacing assoc with assoc! kind regards Am Freitag, 16. September 2011 schrieb Herwig Hochleitner : Am Freitag, 16. September 2011 schrieb David Nolen : The other thing to consider is that - is this a contract that is desirable to support? Transients are only about performance - lowering the time it takes to construct a collection. Perhaps there are faster implementations which cannot fulfill the contract of supporting contains? Fair point! OTOH such an implementation would still need to support get, which is supposed to be fast too (the reason it's stated explicitely in the contains? doc is, so that people don't confuse it with some) In fact, one could implement contains? as (defn contains? [c x] (not= ::not-found (get c x ::not-found))) right now and retain the performance guarantees. And it would work on transients too :) kind regards -- __ Herwig Hochleitner -- __ Herwig Hochleitner -- 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: misuse of or bug in transients?
Am Freitag, 16. September 2011 schrieb David Nolen : I suspect that part of the reason there is little movement on this is that transients are as of 1.3 *still* marked alpha. And from what I understand they will most likely become an implementation detail. That is direct use will be thoroughly discouraged. That makes sense. So we basically have two options now: - make it work - make it an error I'll be glad to help with either. Shall we repost this to the dev list, so that Rich has a chance to look at it? kind regards -- __ Herwig Hochleitner -- 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: misuse of or bug in transients?
On Fri, Sep 16, 2011 at 5:12 PM, Herwig Hochleitner hhochleit...@gmail.comwrote: Am Freitag, 16. September 2011 schrieb David Nolen : I suspect that part of the reason there is little movement on this is that transients are as of 1.3 *still* marked alpha. And from what I understand they will most likely become an implementation detail. That is direct use will be thoroughly discouraged. That makes sense. So we basically have two options now: - make it work - make it an error I will note: It will probably not become an error because of the reasons I mentioned above and there is no reason to single out transients over all the other types that also return false. There are already patches that fix issue and they haven't been applied. David -- 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: misuse of or bug in transients?
Am Freitag, 16. September 2011 schrieb David Nolen : I will note: It will probably not become an error because of the reasons I mentioned above and there is no reason to single out transients over all the other types that also return false. Thanks, I just was about to start a thread on dev about contains? and get being to loosely typed. Your response arrived JIT to make me reread your comment about heterogenous collections. The reason to single out transients is that returning false/nil from contains?/get, is a particularly bad interaction after having read http://clojure.org/Transients where it says: Transients support the read-only interface of the source, i.e. you can call *nth*, *get*, *count* and fn-call a transient vector, just like a persistent vector. Since contains? and get on a transient return faulty values anyway, contrary to the doc, why not make it a NotImplementedError for 1.3.0? There are already patches that fix issue and they haven't been applied. True. But Rich didn't seem averse to the idea of making it defined behavior, either. -- 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: misuse of or bug in transients?
IMO, get and contains? should work on transients. If the fn-call variant of get works, the others can for transients be defined in terms of that. Add containsKey to ITransientAssociative and implement containsKey on transient sets and maps to do what calling them as functions does, and the problem is completely solved. I can't see why there'd be any controversy over this, by the way. The behavior violates least surprise, is contrary to the written docu, and is easily fixed without worsening the transients' current performance. -- Protege: What is this seething mass of parentheses?! Master: Your father's Lisp REPL. This is the language of a true hacker. Not as clumsy or random as C++; a language for a more civilized age. -- 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