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... Thanks, Jon > On Nov 1, 2017, at 10:02 AM, Stephen Canon via swift-dev > <swift-dev@swift.org> wrote: > > > >> On Nov 1, 2017, at 12:51 PM, Greg Titus via swift-dev <swift-dev@swift.org> >> wrote: >> >>> On Nov 1, 2017, at 9:16 AM, Ben Cohen via swift-dev <swift-dev@swift.org> >>> wrote: >>>> On Oct 31, 2017, at 10:11 PM, Chris Lattner via swift-dev >>>> <swift-dev@swift.org> wrote: >>>> On Oct 31, 2017, at 9:07 AM, Stephen Canon via swift-dev >>>> <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