> On Nov 2, 2017, at 5:20 PM, Jonathan Hull via swift-dev <swift-dev@swift.org> > wrote: > > It looks like we have a good solution. Per Steve and David’s suggestions: > > 1) Make FloatingPoint == reflexive > > 2) Add &== to FloatingPoint for those who specifically want IEEE behavior > > 3) Add a warning + fixit to ‘a != a’ > > We should take this to evolution…
Looks like a winner to me. > > Thanks, > Jon > >> On Nov 1, 2017, at 10:02 AM, Stephen Canon via swift-dev >> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote: >> >> >> >>> On Nov 1, 2017, at 12:51 PM, Greg Titus via swift-dev <swift-dev@swift.org >>> <mailto:swift-dev@swift.org>> wrote: >>> >>>> On Nov 1, 2017, at 9:16 AM, Ben Cohen via swift-dev <swift-dev@swift.org >>>> <mailto:swift-dev@swift.org>> wrote: >>>>> On Oct 31, 2017, at 10:11 PM, Chris Lattner via swift-dev >>>>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote: >>>>> On Oct 31, 2017, at 9:07 AM, Stephen Canon via swift-dev >>>>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote: >>>>>> [Replying to the thread as a whole] >>>>>> >>>>>> There have been a bunch of suggestions for variants of `==` that either >>>>>> trap on NaN or return `Bool?`. I think that these suggestions result >>>>>> from people getting tunnel-vision on the idea of “make FloatingPoint >>>>>> equality satisfy desired axioms of Equatable / Comparable”. This is >>>>>> misguided. Our goal is (should be) to make a language usable by >>>>>> developers; satisfying axioms is only useful in as much as they serve >>>>>> that goal. >>>>>> >>>>>> Trapping or returning `Bool?` does not make it easier to write correct >>>>>> concrete code, and it does not enable writing generic algorithms that >>>>>> operate on Comparable or Equatable. Those are the problems to be solved. >>>>> >>>>> +100. Swift isn’t the first language to face the problems of floating >>>>> point, nor is it the first to try to shoehorn it into a framework like >>>>> Equatable. >>>> >>>> Java and C# do not have this problem with their generic algorithms (albeit >>>> possibly because of limitations in their languages that Swift doesn’t >>>> have). Swift is setting itself up as a major language with confusing and >>>> unjustifiable behavior by comparison. That some other languages are also >>>> bad at this doesn’t seem relevant. >>> >>> The common (and correct!) wisdom in _any_ programming language that uses >>> IEEE floating point is that checking equality of two floating point values >>> is almost always a terrible idea. Usually what you want in any real world >>> code is to check for a difference less than some epsilon value, which >>> depends upon context. There are just too many issues with values that >>> aren’t exactly representable, rounding errors during computations, et >>> cetera, for perfectly normal floats even if you completely left aside >>> equality rules for NaN. >> >> The common wisdom is fundamentally bogus. One should *often* use a tolerance >> for floating-point comparison, but there’s a whole host of situations in >> which exact equality is perfectly appropriate. Of particular note for us, >> those situations include most generic contexts based on Equatable or >> Comparable. >> >> s.contains(2) >> >> should not return `true` if `s` contains something two-ish. It should return >> `true` if and only if `s` contains the actual value `2`. >> >> One might want to have an additional method on sets of >> FloatingPoint-conforming types that uses a tolerance, but contains should do >> precisely what it says on the tin. >> >>> I completely understand the desire in this thread to make floating point >>> really satisfy the axioms of Equatable, but the fact is, even if you did, >>> using a generic algorithm that depends upon equatability with floating >>> point types is almost always just a programming error waiting to happen. >>> It’s implicit in the representation and use of floating point values >>> themselves, no matter what particular implementation you decide on for == >>> or &==. >>> >>> If you really want to make the language better for developers, provide and >>> emphasize fixed point or infinite precision or rational types for doing >>> various things instead, and encourage them to shun floats as much as >>> possible. If you really need to change anything about the standard library >>> of Swift, my preferred solution would be to continue to provide ==(lhs : >>> Float, rhs: Float) and != but NOT declare conformance to Equatable at all >>> so that generic algorithms involving floats would fail to compile. >> >> Fixed point representations have their place[1], but rationals are strictly >> worse than floating-point representations in every way except for their >> ability to exactly represent 1/3 in toy problems and efficiency of division >> until you saturate the size of the denominator. I am not exaggerating. They >> waste space, they have a highly non-uniform distribution of representable >> values, they have many redundant representations, and denominators grow >> exponentially in almost every non-toy problem. >> >> Floating-point is the worst approximation to the real numbers except for all >> the others. >> >> – Steve >> >> [1] Unfortunately they are generally unusable for libraries due to complete >> lack of scale invariance. This can be worked around, but doing so requires >> more hand-holding than floating-point. >> _______________________________________________ >> swift-dev mailing list >> swift-dev@swift.org <mailto:swift-dev@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-dev >> <https://lists.swift.org/mailman/listinfo/swift-dev> > _______________________________________________ > swift-dev mailing list > swift-dev@swift.org > https://lists.swift.org/mailman/listinfo/swift-dev
_______________________________________________ swift-dev mailing list swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev