Re: Set equality bug?
Obviously... user=> (= (byte 1) (short 1) (long 1) 1) true user=> http://clojure.org/rationale Language as platform vs. language + platform - Old way - each language defines its own runtime GC, bytecode, type system, libraries etc - New way (JVM, .Net) - Common runtime independent of language Clojure 'type system' embraces the platform it runs on with the exception of its own persistent data structures. It's not the other way around. On Fri, 23 Jan 2015 14:23:34 -0800 (PST) Fluid Dynamics wrote: > And this is not a typeless language, it is a strongly dynamically > typed language. > -- Luc Préfontaine SoftAddicts inc. Québec, Canada Mobil: (514) 993-0320 Fax: (514) 800-2017 -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
And this is not a typeless language, it is a strongly dynamically typed language. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
On Friday, January 23, 2015 at 1:27:18 PM UTC-5, Luc wrote: > > Danger vs flexibility. > > < or > are safe. Should they throw an exception then ? > > Compiler in some older typed languages would warn you about testing > equality between two float numbers irrelevant of their types but would be > silent about other operators. > > Testing equality with floats is seldom used in the context of heavy > computations. Testing against a range is often preferred. > Often, but there can be exceptions. When floats appear as part of objects put in a set or used as map keys is one of them. Not long ago I had something doing numeric work where calculations produced double values and certain runs of inputs would produce identical output, down to the last decimal place. Detecting such runs was as simple as using a map with double keys and checking whether it already had an entry for a value, then dispatching some other code based on the value found, as inputs that produced one value needed one sort of additional processing, and another value another sort. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
Danger vs flexibility. < or > are safe. Should they throw an exception then ? Compiler in some older typed languages would warn you about testing equality between two float numbers irrelevant of their types but would be silent about other operators. Testing equality with floats is seldom used in the context of heavy computations. Testing against a range is often preferred. Money related apps use specific types to deal with rounding/truncating. This is why packed decimal was used intensively. You would always end up with two decimals. W/o having to care for the intermediate computation steps too much. Danger comes from ignorance. What you with it afterward is another story :) I would find it odd to see some operators throw such errors in a typeless language. > If the underlying argument is that it is horribly dangerous to mix floats > and doubles in your code, then maybe (<= (float 1.5) (double 1.5)) should > have the semantics of (.compareTo (float 1.5) (double 1.5)), i.e., throw an > error. > > I'm not certain that's a good idea for Clojure, but it does seem like the > logical outcome of this line of thinking. > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- Luc Prefontaine sent by ibisMail! -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
If the underlying argument is that it is horribly dangerous to mix floats and doubles in your code, then maybe (<= (float 1.5) (double 1.5)) should have the semantics of (.compareTo (float 1.5) (double 1.5)), i.e., throw an error. I'm not certain that's a good idea for Clojure, but it does seem like the logical outcome of this line of thinking. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
On Jan 23, 2015, at 11:51 AM, Andy Fingerhut wrote: > Hash consistency is certainly nice, but if Clojure were changed such that (= > float-val double-val) were always false, and no other changes were made, it > would lead to this situation: > > user=> (<= (float 1.5) (double 1.5)) > true > user=> (>= (float 1.5) (double 1.5)) > true > user=> (= (float 1.5) (double 1.5)) > false I'd argue you should be using == if you care about that particular property. And note that this can already happen with BigDecimals: user=> (>= 10M 10) true user=> (<= 10M 10) true user=> (= 10M 10) false -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
Not sure which properties you prefer to be true in programming languages you use. Hash consistency is certainly nice, but if Clojure were changed such that (= float-val double-val) were always false, and no other changes were made, it would lead to this situation: user=> (<= (float 1.5) (double 1.5)) true user=> (>= (float 1.5) (double 1.5)) true user=> (= (float 1.5) (double 1.5)) false That certainly flies in the face of what most people learned in math class. Andy On Fri, Jan 23, 2015 at 9:29 AM, Michael Gardner wrote: > On Jan 23, 2015, at 8:23 AM, Andy Fingerhut > wrote: > > You can try creating a JIRA ticket suggesting that Clojure's = should > return false when comparing floats and doubles to each other. > > CLJ-1649, for anyone interested. > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
On Jan 23, 2015, at 8:23 AM, Andy Fingerhut wrote: > You can try creating a JIRA ticket suggesting that Clojure's = should return > false when comparing floats and doubles to each other. CLJ-1649, for anyone interested. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
Michael: You can try creating a JIRA ticket suggesting that Clojure's = should return false when comparing floats and doubles to each other. I have no idea if it would go anywhere, but alternative (2) trying to get hashes to be equal between = float/doubles has been suggested and declined. Without some new convincing argument in favor of (2), it seems unlikely to change. Another alternative might be an option to throw an exception if any floats creep into Clojure territory from Java, if that boundary line is even drawable. Andy On Fri, Jan 23, 2015 at 4:45 AM, Michael Gardner wrote: > I'm sure we are all aware of the various issues with floating point math > (particularly equality comparisons); however none of that is relevant to > this discussion. The only issue here is an inconsistency between hashing > and equality testing in Clojure. > > My claim is that the property "any two objects can be equal only if their > hashes are equal" is a fundamental one that should not be violated under > any circumstances. Whether that means modifying Clojure's hashing algorithm > or its implementation of = doesn't much matter to me, so long as that > property is maintained. > > > On Jan 23, 2015, at 5:06 AM, Luc Préfontaine < > lprefonta...@softaddicts.ca> wrote: > > > > Well if it breaks elsewhere than in your code because you mix > representations and leak > > them to some library in Java that you do not control I see my comments > as absolutely relevant. > > > > It's not technical, it's failsafe. But that might not be of any interest > to your problem scope. > > However it does interest me. Hiding odd behaviors when consistency can > be guaranteed, > > I have no problem with that. Here to me its very clear that there is no > failsafe approach. > > > > Clojure is hosted on a platform that does not provide the kind if > consistency you want. > > Anything you can build to hide this in Clojure is like building a tower > on moving sand. > > > > Mark has a valid point about type safety which helps a bit in Java but > you can dig > > with google and you will find people that got bitten in Java by > float/double mixing > > even with type 'safety'. So long for type systems, it cannot help you > with values that > > 'look' the same superficially but are internally different. > > > > For some values, floats and doubles are equal because their internal > representations are the > > same. For many other values it's not working. > > > > I suggest some readings; > > > > http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html > > http://floating-point-gui.de/errors/comparison/ > > > > Then maybe we can bring this thread to an end. > > > > > >> If there's a technical reason why Clojure can't return false for all = > comparisons between floats and doubles, I'd like to hear it. Otherwise, I > don't see how your response is relevant. > >> > >>> On Jan 23, 2015, at 3:10 AM, Luc Prefontaine < > lprefonta...@softaddicts.ca> wrote: > >>> > >>> Agree, it's broken... in java... > >>> Has it has been broken in the past in several architectures... > >>> > >>> I understand your frustration but this is not something new. It's been > a problem for at least 30 years. > >>> > >>> It is kind of a basic programming issue: > >>> > >>> - Never compare floats with different representations. > >>> > >>> - Never mix different representations in computations > >>> > >>> - Convert representations as early as possible to a common format > >>> > >>> These are the rules to follow to avoid running into trouble. > >>> > >>> Now if you think you can overcome this persistent (ah ! ah !) problem > with some David Copperfield trick, fine. > >>> > >>> But that's a trick nothing else. The problem will resurface in some > form in another. Better cope with reality... > >>> > >>> Luc P. > >>> > >>> > On Jan 23, 2015, at 1:33 AM, Immo Heikkinen > wrote: > > > > I actually ran into this while comparing nested data structures from > two different sources and spent a good part of my day figuring out what's > happening. While it is a good advice to avoid mixing floats and doubles, it > is inevitable that Clojure users will get bitten by this once in a while > and hours will be wasted. > > > > It is also very disturbing to realise that "(= a b)" doesn't always > imply "(= (hash a) (hash b))" or "(= #{a} #{b})" as you would think. > > (inc) > > This is fundamentally broken behavior. Telling people to just learn > to avoid it is not good, IMO. If the hashes must be unequal, then = should > return false. > > As for backwards compatibility, note that if such a change were made > to =, it wouldn't affect anyone who was already following Andy's advice to > avoid mixing doubles and floats. IOW, it should only affect those who are > doing something you're not "supposed" to do anyway. > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post t
Re: Set equality bug?
I'm sure we are all aware of the various issues with floating point math (particularly equality comparisons); however none of that is relevant to this discussion. The only issue here is an inconsistency between hashing and equality testing in Clojure. My claim is that the property "any two objects can be equal only if their hashes are equal" is a fundamental one that should not be violated under any circumstances. Whether that means modifying Clojure's hashing algorithm or its implementation of = doesn't much matter to me, so long as that property is maintained. > On Jan 23, 2015, at 5:06 AM, Luc Préfontaine > wrote: > > Well if it breaks elsewhere than in your code because you mix representations > and leak > them to some library in Java that you do not control I see my comments as > absolutely relevant. > > It's not technical, it's failsafe. But that might not be of any interest to > your problem scope. > However it does interest me. Hiding odd behaviors when consistency can be > guaranteed, > I have no problem with that. Here to me its very clear that there is no > failsafe approach. > > Clojure is hosted on a platform that does not provide the kind if consistency > you want. > Anything you can build to hide this in Clojure is like building a tower on > moving sand. > > Mark has a valid point about type safety which helps a bit in Java but you > can dig > with google and you will find people that got bitten in Java by float/double > mixing > even with type 'safety'. So long for type systems, it cannot help you with > values that > 'look' the same superficially but are internally different. > > For some values, floats and doubles are equal because their internal > representations are the > same. For many other values it's not working. > > I suggest some readings; > > http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html > http://floating-point-gui.de/errors/comparison/ > > Then maybe we can bring this thread to an end. > > >> If there's a technical reason why Clojure can't return false for all = >> comparisons between floats and doubles, I'd like to hear it. Otherwise, I >> don't see how your response is relevant. >> >>> On Jan 23, 2015, at 3:10 AM, Luc Prefontaine >>> wrote: >>> >>> Agree, it's broken... in java... >>> Has it has been broken in the past in several architectures... >>> >>> I understand your frustration but this is not something new. It's been a >>> problem for at least 30 years. >>> >>> It is kind of a basic programming issue: >>> >>> - Never compare floats with different representations. >>> >>> - Never mix different representations in computations >>> >>> - Convert representations as early as possible to a common format >>> >>> These are the rules to follow to avoid running into trouble. >>> >>> Now if you think you can overcome this persistent (ah ! ah !) problem with >>> some David Copperfield trick, fine. >>> >>> But that's a trick nothing else. The problem will resurface in some form in >>> another. Better cope with reality... >>> >>> Luc P. >>> >>> On Jan 23, 2015, at 1:33 AM, Immo Heikkinen wrote: > > I actually ran into this while comparing nested data structures from two > different sources and spent a good part of my day figuring out what's > happening. While it is a good advice to avoid mixing floats and doubles, > it is inevitable that Clojure users will get bitten by this once in a > while and hours will be wasted. > > It is also very disturbing to realise that "(= a b)" doesn't always imply > "(= (hash a) (hash b))" or "(= #{a} #{b})" as you would think. (inc) This is fundamentally broken behavior. Telling people to just learn to avoid it is not good, IMO. If the hashes must be unequal, then = should return false. As for backwards compatibility, note that if such a change were made to =, it wouldn't affect anyone who was already following Andy's advice to avoid mixing doubles and floats. IOW, it should only affect those who are doing something you're not "supposed" to do anyway. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. >>> -- >>> Luc Prefontaine sent by ibisMail! >>>
Re: Set equality bug?
public class TestClass { public static void equality () { double dd = 3.5; float ff = 3.5f; System.out.println(String.format("dd vs ff == %b", dd==ff)); double dd2 = 3.2; float ff2 = 3.2f; System.out.println(String.format("dd2 vs ff2 == %b", dd2==ff2)); } } REPL output: => (idem.core.TestClass/equality) nil Console output: nREPL server started on port 38698 on host 127.0.0.1 - nrepl://127.0.0.1:38698 dd vs ff == true dd2 vs ff2 == false We are talking about values as primitive types, not boxed values as objects: The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true). => (class (float 3.2)) java.lang.Float => (class (double 3.2)) java.lang.Double Oupse... :) Luc P. On Fri, 23 Jan 2015 01:31:31 -0800 Mark Engelberg wrote: > On Fri, Jan 23, 2015 at 1:10 AM, Luc Prefontaine < > lprefonta...@softaddicts.ca> wrote: > > > Agree, it's broken... in java... > > > > I think it's more frustrating in Clojure than in Java, though, > because in Java you have those big, ugly type annotations on every > single variable, input and output, so there's really no question when > you're working with a mixture of floats and doubles. In Clojure, > it's much easier for this kind of thing to slip into your program > unnoticed. Call a couple of external libraries that produce floats > or doubles -- Clojure will happily hide the difference from you and > then you get burned. > > As I frequently find myself explaining to newcomers to Clojure, one of > Clojure's biggest weaknesses is that it goes to great pains to hide > type details (floats vs doubles, boxed vs unboxed, hash sets vs array > sets, etc.) and every once in a while it really matters -- a lot -- > what the types actually are and there aren't many tools for > discovering the flow of types through your code. > > So I wouldn't necessarily go blaming this on Java. > > Furthermore, I'm not so sure it is broken in Java: > > => (.equals (float 2) (double 2)) > false > > => (.compareTo (float 2) (double 2)) > ClassCastException Cannot cast java.lang.Double to java.lang.Float > java.lang.Class.cast (Class.java:3258) > > So Java doesn't appear to transparently treat floats and doubles as > equal (which is consistent with the fact that Java's hashes of floats > and doubles can be different). > -- Luc Préfontaine SoftAddicts inc. Québec, Canada Mobil: (514) 993-0320 Fax: (514) 800-2017 -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
Well if it breaks elsewhere than in your code because you mix representations and leak them to some library in Java that you do not control I see my comments as absolutely relevant. It's not technical, it's failsafe. But that might not be of any interest to your problem scope. However it does interest me. Hiding odd behaviors when consistency can be guaranteed, I have no problem with that. Here to me its very clear that there is no failsafe approach. Clojure is hosted on a platform that does not provide the kind if consistency you want. Anything you can build to hide this in Clojure is like building a tower on moving sand. Mark has a valid point about type safety which helps a bit in Java but you can dig with google and you will find people that got bitten in Java by float/double mixing even with type 'safety'. So long for type systems, it cannot help you with values that 'look' the same superficially but are internally different. For some values, floats and doubles are equal because their internal representations are the same. For many other values it's not working. I suggest some readings; http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html http://floating-point-gui.de/errors/comparison/ Then maybe we can bring this thread to an end. > If there's a technical reason why Clojure can't return false for all = > comparisons between floats and doubles, I'd like to hear it. Otherwise, I > don't see how your response is relevant. > > > On Jan 23, 2015, at 3:10 AM, Luc Prefontaine > > wrote: > > > > Agree, it's broken... in java... > > Has it has been broken in the past in several architectures... > > > > I understand your frustration but this is not something new. It's been a > > problem for at least 30 years. > > > > It is kind of a basic programming issue: > > > > - Never compare floats with different representations. > > > > - Never mix different representations in computations > > > > - Convert representations as early as possible to a common format > > > > These are the rules to follow to avoid running into trouble. > > > > Now if you think you can overcome this persistent (ah ! ah !) problem with > > some David Copperfield trick, fine. > > > > But that's a trick nothing else. The problem will resurface in some form in > > another. Better cope with reality... > > > > Luc P. > > > > > >> On Jan 23, 2015, at 1:33 AM, Immo Heikkinen > >> wrote: > >>> > >>> I actually ran into this while comparing nested data structures from two > >>> different sources and spent a good part of my day figuring out what's > >>> happening. While it is a good advice to avoid mixing floats and doubles, > >>> it is inevitable that Clojure users will get bitten by this once in a > >>> while and hours will be wasted. > >>> > >>> It is also very disturbing to realise that "(= a b)" doesn't always imply > >>> "(= (hash a) (hash b))" or "(= #{a} #{b})" as you would think. > >> > >> (inc) > >> > >> This is fundamentally broken behavior. Telling people to just learn to > >> avoid it is not good, IMO. If the hashes must be unequal, then = should > >> return false. > >> > >> As for backwards compatibility, note that if such a change were made to =, > >> it wouldn't affect anyone who was already following Andy's advice to avoid > >> mixing doubles and floats. IOW, it should only affect those who are doing > >> something you're not "supposed" to do anyway. > >> > >> -- > >> You received this message because you are subscribed to the Google > >> Groups "Clojure" group. > >> To post to this group, send email to clojure@googlegroups.com > >> Note that posts from new members are moderated - please be patient with > >> your first post. > >> To unsubscribe from this group, send email to > >> clojure+unsubscr...@googlegroups.com > >> For more options, visit this group at > >> http://groups.google.com/group/clojure?hl=en > >> --- > >> You received this message because you are subscribed to the Google Groups > >> "Clojure" group. > >> To unsubscribe from this group and stop receiving emails from it, send an > >> email to clojure+unsubscr...@googlegroups.com. > >> For more options, visit https://groups.google.com/d/optout. > >> > > -- > > Luc Prefontaine sent by ibisMail! > > > > -- > > You received this message because you are subscribed to the Google > > Groups "Clojure" group. > > To post to this group, send email to clojure@googlegroups.com > > Note that posts from new members are moderated - please be patient with > > your first post. > > To unsubscribe from this group, send email to > > clojure+unsubscr...@googlegroups.com > > For more options, visit this group at > > http://groups.google.com/group/clojure?hl=en > > --- > > You received this message because you are subscribed to the Google Groups > > "Clojure" group. > > To unsubscribe from this group and stop receiving emails from it, send an > > email to clojure+unsubscr...@googlegroups.com. > > For more options, vi
Re: Set equality bug?
If there's a technical reason why Clojure can't return false for all = comparisons between floats and doubles, I'd like to hear it. Otherwise, I don't see how your response is relevant. > On Jan 23, 2015, at 3:10 AM, Luc Prefontaine > wrote: > > Agree, it's broken... in java... > Has it has been broken in the past in several architectures... > > I understand your frustration but this is not something new. It's been a > problem for at least 30 years. > > It is kind of a basic programming issue: > > - Never compare floats with different representations. > > - Never mix different representations in computations > > - Convert representations as early as possible to a common format > > These are the rules to follow to avoid running into trouble. > > Now if you think you can overcome this persistent (ah ! ah !) problem with > some David Copperfield trick, fine. > > But that's a trick nothing else. The problem will resurface in some form in > another. Better cope with reality... > > Luc P. > > >> On Jan 23, 2015, at 1:33 AM, Immo Heikkinen wrote: >>> >>> I actually ran into this while comparing nested data structures from two >>> different sources and spent a good part of my day figuring out what's >>> happening. While it is a good advice to avoid mixing floats and doubles, it >>> is inevitable that Clojure users will get bitten by this once in a while >>> and hours will be wasted. >>> >>> It is also very disturbing to realise that "(= a b)" doesn't always imply >>> "(= (hash a) (hash b))" or "(= #{a} #{b})" as you would think. >> >> (inc) >> >> This is fundamentally broken behavior. Telling people to just learn to avoid >> it is not good, IMO. If the hashes must be unequal, then = should return >> false. >> >> As for backwards compatibility, note that if such a change were made to =, >> it wouldn't affect anyone who was already following Andy's advice to avoid >> mixing doubles and floats. IOW, it should only affect those who are doing >> something you're not "supposed" to do anyway. >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with your >> first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > -- > Luc Prefontaine sent by ibisMail! > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
On Fri, Jan 23, 2015 at 1:10 AM, Luc Prefontaine < lprefonta...@softaddicts.ca> wrote: > Agree, it's broken... in java... > I think it's more frustrating in Clojure than in Java, though, because in Java you have those big, ugly type annotations on every single variable, input and output, so there's really no question when you're working with a mixture of floats and doubles. In Clojure, it's much easier for this kind of thing to slip into your program unnoticed. Call a couple of external libraries that produce floats or doubles -- Clojure will happily hide the difference from you and then you get burned. As I frequently find myself explaining to newcomers to Clojure, one of Clojure's biggest weaknesses is that it goes to great pains to hide type details (floats vs doubles, boxed vs unboxed, hash sets vs array sets, etc.) and every once in a while it really matters -- a lot -- what the types actually are and there aren't many tools for discovering the flow of types through your code. So I wouldn't necessarily go blaming this on Java. Furthermore, I'm not so sure it is broken in Java: => (.equals (float 2) (double 2)) false => (.compareTo (float 2) (double 2)) ClassCastException Cannot cast java.lang.Double to java.lang.Float java.lang.Class.cast (Class.java:3258) So Java doesn't appear to transparently treat floats and doubles as equal (which is consistent with the fact that Java's hashes of floats and doubles can be different). -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
Agree, it's broken... in java... Has it has been broken in the past in several architectures... I understand your frustration but this is not something new. It's been a problem for at least 30 years. It is kind of a basic programming issue: - Never compare floats with different representations. - Never mix different representations in computations - Convert representations as early as possible to a common format These are the rules to follow to avoid running into trouble. Now if you think you can overcome this persistent (ah ! ah !) problem with some David Copperfield trick, fine. But that's a trick nothing else. The problem will resurface in some form in another. Better cope with reality... Luc P. > On Jan 23, 2015, at 1:33 AM, Immo Heikkinen wrote: > > > > I actually ran into this while comparing nested data structures from two > > different sources and spent a good part of my day figuring out what's > > happening. While it is a good advice to avoid mixing floats and doubles, it > > is inevitable that Clojure users will get bitten by this once in a while > > and hours will be wasted. > > > > It is also very disturbing to realise that "(= a b)" doesn't always imply > > "(= (hash a) (hash b))" or "(= #{a} #{b})" as you would think. > > (inc) > > This is fundamentally broken behavior. Telling people to just learn to avoid > it is not good, IMO. If the hashes must be unequal, then = should return > false. > > As for backwards compatibility, note that if such a change were made to =, it > wouldn't affect anyone who was already following Andy's advice to avoid > mixing doubles and floats. IOW, it should only affect those who are doing > something you're not "supposed" to do anyway. > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- Luc Prefontaine sent by ibisMail! -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
On Jan 23, 2015, at 1:33 AM, Immo Heikkinen wrote: > > I actually ran into this while comparing nested data structures from two > different sources and spent a good part of my day figuring out what's > happening. While it is a good advice to avoid mixing floats and doubles, it > is inevitable that Clojure users will get bitten by this once in a while and > hours will be wasted. > > It is also very disturbing to realise that "(= a b)" doesn't always imply "(= > (hash a) (hash b))" or "(= #{a} #{b})" as you would think. (inc) This is fundamentally broken behavior. Telling people to just learn to avoid it is not good, IMO. If the hashes must be unequal, then = should return false. As for backwards compatibility, note that if such a change were made to =, it wouldn't affect anyone who was already following Andy's advice to avoid mixing doubles and floats. IOW, it should only affect those who are doing something you're not "supposed" to do anyway. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
I actually ran into this while comparing nested data structures from two different sources and spent a good part of my day figuring out what's happening. While it is a good advice to avoid mixing floats and doubles, it is inevitable that Clojure users will get bitten by this once in a while and hours will be wasted. It is also very disturbing to realise that "(= a b)" doesn't always imply "(= (hash a) (hash b))" or "(= #{a} #{b})" as you would think. 2015-01-23 0:18 GMT+02:00 Andy Fingerhut : > Part of what you wish were true is already true: Using = to compare a > double to a BigDecimal always returns false in Clojure, as does comparing a > float to a BigDecimal. > > It is only (= float-value double-value) that can return true in Clojure, > even though hash does not guarantee the usual hash consistency property of > "(= a b) implies (= (hash a) (hash b))". Hence my recommendation earlier > in the thread to avoid mixing floats and doubles in the same Clojure > program. > > Andy > > On Thu, Jan 22, 2015 at 2:04 PM, Fluid Dynamics > wrote: > >> On Thursday, January 22, 2015 at 2:12:52 PM UTC-5, Jozef Wagner wrote: >>> >>> As seen in CLJ-1372, this issue will probably cause some strong >>> opinions. I think this is an example of a leaky abstraction and the current >>> approach is to leave it as is, as there are some serious trade-offs and are >>> there is no rationale or real practical reason to fix this. >>> >>> Current implementation for double and float hashes uses Java's hash >>> algorithm, which >>> uses IEEE 754 bit representation of floats, that is a fast native >>> function [1], but is different for doubles and floats. While Murmur3 does >>> provide hashing for integer numbers, there is no hash function for floating >>> point ones. >>> >>> And note that there are big decimals too... >>> >>> > (hash 1.5) >>> 1073217536 >>> > (hash 1.5M) >>> 466 >>> > (hash (float 1.5)) >>> 1069547520 >>> >> >> Things that don't have the same hash shouldn't compare equal, at least so >> long as one avoids mutable java.util collections. >> >> If floats and doubles can't generally have the same hashes (let alone >> floats and BigDecimals) then = should return false for any comparison of >> two different of these three types (and numerical code that wants to check >> for numerical equality across types, to the extent that ever makes sense >> with FP types, should use ==). >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
Part of what you wish were true is already true: Using = to compare a double to a BigDecimal always returns false in Clojure, as does comparing a float to a BigDecimal. It is only (= float-value double-value) that can return true in Clojure, even though hash does not guarantee the usual hash consistency property of "(= a b) implies (= (hash a) (hash b))". Hence my recommendation earlier in the thread to avoid mixing floats and doubles in the same Clojure program. Andy On Thu, Jan 22, 2015 at 2:04 PM, Fluid Dynamics wrote: > On Thursday, January 22, 2015 at 2:12:52 PM UTC-5, Jozef Wagner wrote: >> >> As seen in CLJ-1372, this issue will probably cause some strong opinions. >> I think this is an example of a leaky abstraction and the current approach >> is to leave it as is, as there are some serious trade-offs and are there is >> no rationale or real practical reason to fix this. >> >> Current implementation for double and float hashes uses Java's hash >> algorithm, which >> uses IEEE 754 bit representation of floats, that is a fast native >> function [1], but is different for doubles and floats. While Murmur3 does >> provide hashing for integer numbers, there is no hash function for floating >> point ones. >> >> And note that there are big decimals too... >> >> > (hash 1.5) >> 1073217536 >> > (hash 1.5M) >> 466 >> > (hash (float 1.5)) >> 1069547520 >> > > Things that don't have the same hash shouldn't compare equal, at least so > long as one avoids mutable java.util collections. > > If floats and doubles can't generally have the same hashes (let alone > floats and BigDecimals) then = should return false for any comparison of > two different of these three types (and numerical code that wants to check > for numerical equality across types, to the extent that ever makes sense > with FP types, should use ==). > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
On Thursday, January 22, 2015 at 2:12:52 PM UTC-5, Jozef Wagner wrote: > > As seen in CLJ-1372, this issue will probably cause some strong opinions. > I think this is an example of a leaky abstraction and the current approach > is to leave it as is, as there are some serious trade-offs and are there is > no rationale or real practical reason to fix this. > > Current implementation for double and float hashes uses Java's hash > algorithm, which > uses IEEE 754 bit representation of floats, that is a fast native > function [1], but is different for doubles and floats. While Murmur3 does > provide hashing for integer numbers, there is no hash function for floating > point ones. > > And note that there are big decimals too... > > > (hash 1.5) > 1073217536 > > (hash 1.5M) > 466 > > (hash (float 1.5)) > 1069547520 > Things that don't have the same hash shouldn't compare equal, at least so long as one avoids mutable java.util collections. If floats and doubles can't generally have the same hashes (let alone floats and BigDecimals) then = should return false for any comparison of two different of these three types (and numerical code that wants to check for numerical equality across types, to the extent that ever makes sense with FP types, should use ==). -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
As seen in CLJ-1372, this issue will probably cause some strong opinions. I think this is an example of a leaky abstraction and the current approach is to leave it as is, as there are some serious trade-offs and are there is no rationale or real practical reason to fix this. Current implementation for double and float hashes uses Java's hash algorithm, which uses IEEE 754 bit representation of floats, that is a fast native function [1], but is different for doubles and floats. While Murmur3 does provide hashing for integer numbers, there is no hash function for floating point ones. And note that there are big decimals too... > (hash 1.5) 1073217536 > (hash 1.5M) 466 > (hash (float 1.5)) 1069547520 [1] http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/a7dd84b9557c/src/share/classes/java/lang/Double.java#l761 Jozef On Thu, Jan 22, 2015 at 4:36 PM, Luc Préfontaine < lprefonta...@softaddicts.ca> wrote: > And how to you want to proceed knowing that floats and double can escape > elsewhere in your app and create the same chaotic effect like for example, > in some interop call to some obscure library ? > > The best ... consistency here seems to reflect what's occurring underneath > instead > of giving the false impression that everything is fine. > > Floats and doubles do not have the same precision/representation and thus > comparing > for equal values without explicit casting/truncating/rounding cannot be > relied on. > These are JVM native types. Even Java folks ask this question about > equality on a regular > basis and its their language of choice :) > > Have a look at IEE floating point representations that will give you an > idea of the scope > of the problem. > > In the past I used to deal with up to 4 different representations on the > same hardware. > We would never mix them, we would convert them at the edge of our app or > within > very narrow boundaries. > > Even business apps in Cobol had issues with this, not all hardware > supported packed > decimal operations, relying on some floating point representation better > handled by > hardware was common with all the conversion problems related > (rounding/truncating > in computations, ...). We could even choose the runtime float > representation to > minimize errors in computations and take the best one given the app at > hand. > > Avoid mixing them. That's the only safe escape. > > Luc P. > > > My one cent: > > > > But I think (and it's just my humble opinion) is in the scope of Clojure > > keep its consistency, am I right? > > > > I mean, if doubles and floats are different, and they are, I think we > > should always get equality test as false. Or always as true, if they're > > nominally the same value. > > > > Regards > > > > Plínio > > > > On Thu, Jan 22, 2015 at 12:18 PM, Andy Fingerhut < > andy.finger...@gmail.com> > > wrote: > > > > > "It is out of scope for Clojure to fix this for Java types > Float/Double" > > > -- comments in CLJ-1036: http://dev.clojure.org/jira/browse/CLJ-1036 > > > > > > Andy > > > > > > On Thu, Jan 22, 2015 at 5:53 AM, Nicola Mometto > > > wrote: > > > > > >> > > >> Not sure if this is intended behaviour: > > >> user=> (= (float 1.6) (double 1.6)) > > >> false > > >> user=> (= (float 1.5) (double 1.5)) > > >> true > > >> > > >> I.e. = (and ==) will return true when comparing floats with doubles > IFF > > >> the float's .doubleValue roundtrips to the same double it's comparing > to. > > >> > > >> user=> (.doubleValue (float 1.6)) > > >> 1.60023841858 > > >> user=> (.doubleValue (float 1.5)) > > >> 1.5 > > >> > > >> I'm not sure why floats are not handled specially in Numbers.java so > > >> that hash/comparision is handled consistently with doubles (e.g. by > > >> converting the floats to the fitting double via Double.parseDouble), > > >> the current behaviour seems odd to me. > > >> > > >> Jozef Wagner writes: > > >> > > >> > More on this behavior http://dev.clojure.org/jira/browse/CLJ-1036 > > >> > > > >> > On Thu, Jan 22, 2015 at 2:00 PM, Nicola Mometto < > brobro...@gmail.com> > > >> wrote: > > >> > > > >> >> > > >> >> Looking at the PHM impl, this looks like it's caused by (float > 0.5) and > > >> >> (double 0.5) hashing differently. > > >> >> > > >> >> user=> (= (float 0.5) (double 0.5)) > > >> >> true > > >> >> user=> (map hash [(float 0.5) (double 0.5)]) > > >> >> (1056964608 1071644672) > > >> >> > > >> >> Nicola Mometto writes: > > >> >> > > >> >> > Looks like it's a bug in PersistentHashMap: > > >> >> > user=> (contains? (hash-map {:a (float 0.5)} 1) {:a (double 05)}) > > >> >> > false > > >> >> > user=> (contains? (array-map {:a (float 0.5)} 1) {:a (double > 0.5)}) > > >> >> > true > > >> >> > > > >> >> > Immo Heikkinen writes: > > >> >> > > > >> >> >> (= (float 0.5) (double 0.5)) > > >> >> >> => true > > >> >> >> (= #{(float 0.5)} #{(double 0.5)}) > > >> >> >> => true > > >> >> >> (= {:a (float 0.5)} {:a (double 0.5)}) > > >> >> >> => true > > >> >> >> (= #{{:a (float 0.5)}} #{{:a (double 0.5)}}) > > >
Re: Set equality bug?
And how to you want to proceed knowing that floats and double can escape elsewhere in your app and create the same chaotic effect like for example, in some interop call to some obscure library ? The best ... consistency here seems to reflect what's occurring underneath instead of giving the false impression that everything is fine. Floats and doubles do not have the same precision/representation and thus comparing for equal values without explicit casting/truncating/rounding cannot be relied on. These are JVM native types. Even Java folks ask this question about equality on a regular basis and its their language of choice :) Have a look at IEE floating point representations that will give you an idea of the scope of the problem. In the past I used to deal with up to 4 different representations on the same hardware. We would never mix them, we would convert them at the edge of our app or within very narrow boundaries. Even business apps in Cobol had issues with this, not all hardware supported packed decimal operations, relying on some floating point representation better handled by hardware was common with all the conversion problems related (rounding/truncating in computations, ...). We could even choose the runtime float representation to minimize errors in computations and take the best one given the app at hand. Avoid mixing them. That's the only safe escape. Luc P. > My one cent: > > But I think (and it's just my humble opinion) is in the scope of Clojure > keep its consistency, am I right? > > I mean, if doubles and floats are different, and they are, I think we > should always get equality test as false. Or always as true, if they're > nominally the same value. > > Regards > > Plínio > > On Thu, Jan 22, 2015 at 12:18 PM, Andy Fingerhut > wrote: > > > "It is out of scope for Clojure to fix this for Java types Float/Double" > > -- comments in CLJ-1036: http://dev.clojure.org/jira/browse/CLJ-1036 > > > > Andy > > > > On Thu, Jan 22, 2015 at 5:53 AM, Nicola Mometto > > wrote: > > > >> > >> Not sure if this is intended behaviour: > >> user=> (= (float 1.6) (double 1.6)) > >> false > >> user=> (= (float 1.5) (double 1.5)) > >> true > >> > >> I.e. = (and ==) will return true when comparing floats with doubles IFF > >> the float's .doubleValue roundtrips to the same double it's comparing to. > >> > >> user=> (.doubleValue (float 1.6)) > >> 1.60023841858 > >> user=> (.doubleValue (float 1.5)) > >> 1.5 > >> > >> I'm not sure why floats are not handled specially in Numbers.java so > >> that hash/comparision is handled consistently with doubles (e.g. by > >> converting the floats to the fitting double via Double.parseDouble), > >> the current behaviour seems odd to me. > >> > >> Jozef Wagner writes: > >> > >> > More on this behavior http://dev.clojure.org/jira/browse/CLJ-1036 > >> > > >> > On Thu, Jan 22, 2015 at 2:00 PM, Nicola Mometto > >> wrote: > >> > > >> >> > >> >> Looking at the PHM impl, this looks like it's caused by (float 0.5) and > >> >> (double 0.5) hashing differently. > >> >> > >> >> user=> (= (float 0.5) (double 0.5)) > >> >> true > >> >> user=> (map hash [(float 0.5) (double 0.5)]) > >> >> (1056964608 1071644672) > >> >> > >> >> Nicola Mometto writes: > >> >> > >> >> > Looks like it's a bug in PersistentHashMap: > >> >> > user=> (contains? (hash-map {:a (float 0.5)} 1) {:a (double 05)}) > >> >> > false > >> >> > user=> (contains? (array-map {:a (float 0.5)} 1) {:a (double 0.5)}) > >> >> > true > >> >> > > >> >> > Immo Heikkinen writes: > >> >> > > >> >> >> (= (float 0.5) (double 0.5)) > >> >> >> => true > >> >> >> (= #{(float 0.5)} #{(double 0.5)}) > >> >> >> => true > >> >> >> (= {:a (float 0.5)} {:a (double 0.5)}) > >> >> >> => true > >> >> >> (= #{{:a (float 0.5)}} #{{:a (double 0.5)}}) > >> >> >> => false > >> >> >> > >> >> >> > >> >> >> Tested with both 1.6.0 and 1.7.0-alpha5. > >> >> > >> >> -- > >> >> > >> >> -- > >> >> You received this message because you are subscribed to the Google > >> >> Groups "Clojure" group. > >> >> To post to this group, send email to clojure@googlegroups.com > >> >> Note that posts from new members are moderated - please be patient with > >> >> your first post. > >> >> To unsubscribe from this group, send email to > >> >> clojure+unsubscr...@googlegroups.com > >> >> For more options, visit this group at > >> >> http://groups.google.com/group/clojure?hl=en > >> >> --- > >> >> You received this message because you are subscribed to the Google > >> Groups > >> >> "Clojure" group. > >> >> To unsubscribe from this group and stop receiving emails from it, send > >> an > >> >> email to clojure+unsubscr...@googlegroups.com. > >> >> For more options, visit https://groups.google.com/d/optout. > >> >> > >> > >> -- > >> > >> -- > >> You received this message because you are subscribed to the Google > >> Groups "Clojure" group. > >> To post to this group, send email to clojure@googlegroups.com > >> Note that posts from new members are modera
Re: Set equality bug?
On the side of positive recommendations to avoid problems like this, here is some advice: + Don't mix floats and doubles in the same Clojure program. Given that Clojure uses double arithmetic by default, it is much easier to use doubles everywhere than it is to try to use floats everywhere. + Don't use NaN in collections. They aren't even equal to themselves, and that inequality propagates to any collections they are in. + Don't use mutable collections as elements of Clojure's immutable collections. They are equal to each other in straightforward equality tests, but are not consistent in their hashes are, much as float/double values are not. See http://dev.clojure.org/jira/browse/CLJ-1372 for one example. If you keep those things out of Clojure collections, I am not aware of any other gotchas there. Andy On Thu, Jan 22, 2015 at 6:44 AM, Plínio Balduino wrote: > My one cent: > > But I think (and it's just my humble opinion) is in the scope of Clojure > keep its consistency, am I right? > > I mean, if doubles and floats are different, and they are, I think we > should always get equality test as false. Or always as true, if they're > nominally the same value. > > Regards > > Plínio > > On Thu, Jan 22, 2015 at 12:18 PM, Andy Fingerhut > wrote: > >> "It is out of scope for Clojure to fix this for Java types Float/Double" >> -- comments in CLJ-1036: http://dev.clojure.org/jira/browse/CLJ-1036 >> >> Andy >> >> On Thu, Jan 22, 2015 at 5:53 AM, Nicola Mometto >> wrote: >> >>> >>> Not sure if this is intended behaviour: >>> user=> (= (float 1.6) (double 1.6)) >>> false >>> user=> (= (float 1.5) (double 1.5)) >>> true >>> >>> I.e. = (and ==) will return true when comparing floats with doubles IFF >>> the float's .doubleValue roundtrips to the same double it's comparing to. >>> >>> user=> (.doubleValue (float 1.6)) >>> 1.60023841858 >>> user=> (.doubleValue (float 1.5)) >>> 1.5 >>> >>> I'm not sure why floats are not handled specially in Numbers.java so >>> that hash/comparision is handled consistently with doubles (e.g. by >>> converting the floats to the fitting double via Double.parseDouble), >>> the current behaviour seems odd to me. >>> >>> Jozef Wagner writes: >>> >>> > More on this behavior http://dev.clojure.org/jira/browse/CLJ-1036 >>> > >>> > On Thu, Jan 22, 2015 at 2:00 PM, Nicola Mometto >>> wrote: >>> > >>> >> >>> >> Looking at the PHM impl, this looks like it's caused by (float 0.5) >>> and >>> >> (double 0.5) hashing differently. >>> >> >>> >> user=> (= (float 0.5) (double 0.5)) >>> >> true >>> >> user=> (map hash [(float 0.5) (double 0.5)]) >>> >> (1056964608 1071644672) >>> >> >>> >> Nicola Mometto writes: >>> >> >>> >> > Looks like it's a bug in PersistentHashMap: >>> >> > user=> (contains? (hash-map {:a (float 0.5)} 1) {:a (double 0.5)}) >>> >> > false >>> >> > user=> (contains? (array-map {:a (float 0.5)} 1) {:a (double 0.5)}) >>> >> > true >>> >> > >>> >> > Immo Heikkinen writes: >>> >> > >>> >> >> (= (float 0.5) (double 0.5)) >>> >> >> => true >>> >> >> (= #{(float 0.5)} #{(double 0.5)}) >>> >> >> => true >>> >> >> (= {:a (float 0.5)} {:a (double 0.5)}) >>> >> >> => true >>> >> >> (= #{{:a (float 0.5)}} #{{:a (double 0.5)}}) >>> >> >> => false >>> >> >> >>> >> >> >>> >> >> Tested with both 1.6.0 and 1.7.0-alpha5. >>> >> >>> >> -- >>> >> >>> >> -- >>> >> You received this message because you are subscribed to the Google >>> >> Groups "Clojure" group. >>> >> To post to this group, send email to clojure@googlegroups.com >>> >> Note that posts from new members are moderated - please be patient >>> with >>> >> your first post. >>> >> To unsubscribe from this group, send email to >>> >> clojure+unsubscr...@googlegroups.com >>> >> For more options, visit this group at >>> >> http://groups.google.com/group/clojure?hl=en >>> >> --- >>> >> You received this message because you are subscribed to the Google >>> Groups >>> >> "Clojure" group. >>> >> To unsubscribe from this group and stop receiving emails from it, >>> send an >>> >> email to clojure+unsubscr...@googlegroups.com. >>> >> For more options, visit https://groups.google.com/d/optout. >>> >> >>> >>> -- >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clojure@googlegroups.com >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email to >>> clojure+unsubscr...@googlegroups.com >>> For more options, visit this group at >>> http://groups.google.com/group/clojure?hl=en >>> --- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to clojure+unsubscr...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> -- >> You received this message because you are subscribed to the Google >>
Re: Set equality bug?
My one cent: But I think (and it's just my humble opinion) is in the scope of Clojure keep its consistency, am I right? I mean, if doubles and floats are different, and they are, I think we should always get equality test as false. Or always as true, if they're nominally the same value. Regards Plínio On Thu, Jan 22, 2015 at 12:18 PM, Andy Fingerhut wrote: > "It is out of scope for Clojure to fix this for Java types Float/Double" > -- comments in CLJ-1036: http://dev.clojure.org/jira/browse/CLJ-1036 > > Andy > > On Thu, Jan 22, 2015 at 5:53 AM, Nicola Mometto > wrote: > >> >> Not sure if this is intended behaviour: >> user=> (= (float 1.6) (double 1.6)) >> false >> user=> (= (float 1.5) (double 1.5)) >> true >> >> I.e. = (and ==) will return true when comparing floats with doubles IFF >> the float's .doubleValue roundtrips to the same double it's comparing to. >> >> user=> (.doubleValue (float 1.6)) >> 1.60023841858 >> user=> (.doubleValue (float 1.5)) >> 1.5 >> >> I'm not sure why floats are not handled specially in Numbers.java so >> that hash/comparision is handled consistently with doubles (e.g. by >> converting the floats to the fitting double via Double.parseDouble), >> the current behaviour seems odd to me. >> >> Jozef Wagner writes: >> >> > More on this behavior http://dev.clojure.org/jira/browse/CLJ-1036 >> > >> > On Thu, Jan 22, 2015 at 2:00 PM, Nicola Mometto >> wrote: >> > >> >> >> >> Looking at the PHM impl, this looks like it's caused by (float 0.5) and >> >> (double 0.5) hashing differently. >> >> >> >> user=> (= (float 0.5) (double 0.5)) >> >> true >> >> user=> (map hash [(float 0.5) (double 0.5)]) >> >> (1056964608 1071644672) >> >> >> >> Nicola Mometto writes: >> >> >> >> > Looks like it's a bug in PersistentHashMap: >> >> > user=> (contains? (hash-map {:a (float 0.5)} 1) {:a (double 0.5)}) >> >> > false >> >> > user=> (contains? (array-map {:a (float 0.5)} 1) {:a (double 0.5)}) >> >> > true >> >> > >> >> > Immo Heikkinen writes: >> >> > >> >> >> (= (float 0.5) (double 0.5)) >> >> >> => true >> >> >> (= #{(float 0.5)} #{(double 0.5)}) >> >> >> => true >> >> >> (= {:a (float 0.5)} {:a (double 0.5)}) >> >> >> => true >> >> >> (= #{{:a (float 0.5)}} #{{:a (double 0.5)}}) >> >> >> => false >> >> >> >> >> >> >> >> >> Tested with both 1.6.0 and 1.7.0-alpha5. >> >> >> >> -- >> >> >> >> -- >> >> You received this message because you are subscribed to the Google >> >> Groups "Clojure" group. >> >> To post to this group, send email to clojure@googlegroups.com >> >> Note that posts from new members are moderated - please be patient with >> >> your first post. >> >> To unsubscribe from this group, send email to >> >> clojure+unsubscr...@googlegroups.com >> >> For more options, visit this group at >> >> http://groups.google.com/group/clojure?hl=en >> >> --- >> >> You received this message because you are subscribed to the Google >> Groups >> >> "Clojure" group. >> >> To unsubscribe from this group and stop receiving emails from it, send >> an >> >> email to clojure+unsubscr...@googlegroups.com. >> >> For more options, visit https://groups.google.com/d/optout. >> >> >> >> -- >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- 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.g
Re: Set equality bug?
"It is out of scope for Clojure to fix this for Java types Float/Double" -- comments in CLJ-1036: http://dev.clojure.org/jira/browse/CLJ-1036 Andy On Thu, Jan 22, 2015 at 5:53 AM, Nicola Mometto wrote: > > Not sure if this is intended behaviour: > user=> (= (float 1.6) (double 1.6)) > false > user=> (= (float 1.5) (double 1.5)) > true > > I.e. = (and ==) will return true when comparing floats with doubles IFF > the float's .doubleValue roundtrips to the same double it's comparing to. > > user=> (.doubleValue (float 1.6)) > 1.60023841858 > user=> (.doubleValue (float 1.5)) > 1.5 > > I'm not sure why floats are not handled specially in Numbers.java so > that hash/comparision is handled consistently with doubles (e.g. by > converting the floats to the fitting double via Double.parseDouble), > the current behaviour seems odd to me. > > Jozef Wagner writes: > > > More on this behavior http://dev.clojure.org/jira/browse/CLJ-1036 > > > > On Thu, Jan 22, 2015 at 2:00 PM, Nicola Mometto > wrote: > > > >> > >> Looking at the PHM impl, this looks like it's caused by (float 0.5) and > >> (double 0.5) hashing differently. > >> > >> user=> (= (float 0.5) (double 0.5)) > >> true > >> user=> (map hash [(float 0.5) (double 0.5)]) > >> (1056964608 1071644672) > >> > >> Nicola Mometto writes: > >> > >> > Looks like it's a bug in PersistentHashMap: > >> > user=> (contains? (hash-map {:a (float 0.5)} 1) {:a (double 0.5)}) > >> > false > >> > user=> (contains? (array-map {:a (float 0.5)} 1) {:a (double 0.5)}) > >> > true > >> > > >> > Immo Heikkinen writes: > >> > > >> >> (= (float 0.5) (double 0.5)) > >> >> => true > >> >> (= #{(float 0.5)} #{(double 0.5)}) > >> >> => true > >> >> (= {:a (float 0.5)} {:a (double 0.5)}) > >> >> => true > >> >> (= #{{:a (float 0.5)}} #{{:a (double 0.5)}}) > >> >> => false > >> >> > >> >> > >> >> Tested with both 1.6.0 and 1.7.0-alpha5. > >> > >> -- > >> > >> -- > >> You received this message because you are subscribed to the Google > >> Groups "Clojure" group. > >> To post to this group, send email to clojure@googlegroups.com > >> Note that posts from new members are moderated - please be patient with > >> your first post. > >> To unsubscribe from this group, send email to > >> clojure+unsubscr...@googlegroups.com > >> For more options, visit this group at > >> http://groups.google.com/group/clojure?hl=en > >> --- > >> You received this message because you are subscribed to the Google > Groups > >> "Clojure" group. > >> To unsubscribe from this group and stop receiving emails from it, send > an > >> email to clojure+unsubscr...@googlegroups.com. > >> For more options, visit https://groups.google.com/d/optout. > >> > > -- > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
Not sure if this is intended behaviour: user=> (= (float 1.6) (double 1.6)) false user=> (= (float 1.5) (double 1.5)) true I.e. = (and ==) will return true when comparing floats with doubles IFF the float's .doubleValue roundtrips to the same double it's comparing to. user=> (.doubleValue (float 1.6)) 1.60023841858 user=> (.doubleValue (float 1.5)) 1.5 I'm not sure why floats are not handled specially in Numbers.java so that hash/comparision is handled consistently with doubles (e.g. by converting the floats to the fitting double via Double.parseDouble), the current behaviour seems odd to me. Jozef Wagner writes: > More on this behavior http://dev.clojure.org/jira/browse/CLJ-1036 > > On Thu, Jan 22, 2015 at 2:00 PM, Nicola Mometto wrote: > >> >> Looking at the PHM impl, this looks like it's caused by (float 0.5) and >> (double 0.5) hashing differently. >> >> user=> (= (float 0.5) (double 0.5)) >> true >> user=> (map hash [(float 0.5) (double 0.5)]) >> (1056964608 1071644672) >> >> Nicola Mometto writes: >> >> > Looks like it's a bug in PersistentHashMap: >> > user=> (contains? (hash-map {:a (float 0.5)} 1) {:a (double 0.5)}) >> > false >> > user=> (contains? (array-map {:a (float 0.5)} 1) {:a (double 0.5)}) >> > true >> > >> > Immo Heikkinen writes: >> > >> >> (= (float 0.5) (double 0.5)) >> >> => true >> >> (= #{(float 0.5)} #{(double 0.5)}) >> >> => true >> >> (= {:a (float 0.5)} {:a (double 0.5)}) >> >> => true >> >> (= #{{:a (float 0.5)}} #{{:a (double 0.5)}}) >> >> => false >> >> >> >> >> >> Tested with both 1.6.0 and 1.7.0-alpha5. >> >> -- >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
More on this behavior http://dev.clojure.org/jira/browse/CLJ-1036 On Thu, Jan 22, 2015 at 2:00 PM, Nicola Mometto wrote: > > Looking at the PHM impl, this looks like it's caused by (float 0.5) and > (double 0.5) hashing differently. > > user=> (= (float 0.5) (double 0.5)) > true > user=> (map hash [(float 0.5) (double 0.5)]) > (1056964608 1071644672) > > Nicola Mometto writes: > > > Looks like it's a bug in PersistentHashMap: > > user=> (contains? (hash-map {:a (float 0.5)} 1) {:a (double 0.5)}) > > false > > user=> (contains? (array-map {:a (float 0.5)} 1) {:a (double 0.5)}) > > true > > > > Immo Heikkinen writes: > > > >> (= (float 0.5) (double 0.5)) > >> => true > >> (= #{(float 0.5)} #{(double 0.5)}) > >> => true > >> (= {:a (float 0.5)} {:a (double 0.5)}) > >> => true > >> (= #{{:a (float 0.5)}} #{{:a (double 0.5)}}) > >> => false > >> > >> > >> Tested with both 1.6.0 and 1.7.0-alpha5. > > -- > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
Looking at the PHM impl, this looks like it's caused by (float 0.5) and (double 0.5) hashing differently. user=> (= (float 0.5) (double 0.5)) true user=> (map hash [(float 0.5) (double 0.5)]) (1056964608 1071644672) Nicola Mometto writes: > Looks like it's a bug in PersistentHashMap: > user=> (contains? (hash-map {:a (float 0.5)} 1) {:a (double 0.5)}) > false > user=> (contains? (array-map {:a (float 0.5)} 1) {:a (double 0.5)}) > true > > Immo Heikkinen writes: > >> (= (float 0.5) (double 0.5)) >> => true >> (= #{(float 0.5)} #{(double 0.5)}) >> => true >> (= {:a (float 0.5)} {:a (double 0.5)}) >> => true >> (= #{{:a (float 0.5)}} #{{:a (double 0.5)}}) >> => false >> >> >> Tested with both 1.6.0 and 1.7.0-alpha5. -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Set equality bug?
Looks like it's a bug in PersistentHashMap: user=> (contains? (hash-map {:a (float 0.5)} 1) {:a (double 0.5)}) false user=> (contains? (array-map {:a (float 0.5)} 1) {:a (double 0.5)}) true Immo Heikkinen writes: > (= (float 0.5) (double 0.5)) > => true > (= #{(float 0.5)} #{(double 0.5)}) > => true > (= {:a (float 0.5)} {:a (double 0.5)}) > => true > (= #{{:a (float 0.5)}} #{{:a (double 0.5)}}) > => false > > > Tested with both 1.6.0 and 1.7.0-alpha5. -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.