> On Apr 18, 2017, at 8:40 AM, Ben Cohen via swift-evolution
> <[email protected]> wrote:
>
>>
>> On Apr 17, 2017, at 9:40 PM, Chris Lattner via swift-evolution
>> <[email protected] <mailto:[email protected]>> wrote:
>>
>>
>>> On Apr 17, 2017, at 9:07 AM, Joe Groff via swift-evolution
>>> <[email protected] <mailto:[email protected]>> wrote:
>>>
>>>
>>>> On Apr 15, 2017, at 9:49 PM, Xiaodi Wu via swift-evolution
>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>
>>>> For example, I expect `XCTAssertEqual<T : FloatingPoint>(_:_:)` to be
>>>> vended as part of XCTest, in order to make sure that
>>>> `XCTAssertEqual(resultOfComputation, Double.nan)` always fails.
>>>
>>> Unit tests strike me as an example of where you really *don't* want level 1
>>> comparison semantics. If I'm testing the output of an FP operation, I want
>>> to be able to test that it produces nan when I expect it to, or that it
>>> produces the right zero.
>>
>> I find it very concerning that == will have different results based on
>> concrete vs generic type parameters. This can only lead to significant
>> confusion down the road. I’m highly concerned about situations where taking
>> a concrete algorithm and generalizing it (with generics) will change its
>> behavior.
>>
>
> It is already the case that you can start with a concrete algorithm,
> generalize it, and get confusing results – just with a different starting
> point. If you start with a concrete algorithm on Int, then generalize it to
> all Equatable types, then your algorithm will have unexpected behavior for
> floats, because these standard library types fail to follow the rules
> explicitly laid out for conforming to Equatable.
>
> This is bad. Developers need to be able to rely on those rules. The standard
> library certainly does:
>
> let a: [Double] = [(0/0)]
> var b = a
>
> // true, because fast path buffer pointer comparison:
> a == b
>
> b.reserveCapacity(10) // force a reallocation
>
> // now false, because memberwise comparison and nan != nan,
> // violating the reflexivity requirement of Equatable:
> a == b
>
>
> Maybe we could go through and special-case all the places in the standard
> library that rely on this, accounting for the floating point behavior
> (possibly reducing performance as a result). But we shouldn't expect users to.
>
> This is a bump in the rug – push it down in one place, it pops up in another.
> I feel like this proposal at least moves the bump to where fewer people will
> trip over it. I think it highly likely that the intersection of developers
> who understand enough about floating point to write truly correct concrete
> code, but won’t know about or discover the documented difference in generic
> code, is far smaller than the set of people who hit problems with the
> existing behavior.
>
> A more comprehensive solution, with additional protocols or overloads,
> representation of unordered comparison etc, might be able to flatten the rug
> completely, but probably at the cost of introducing complexity that could act
> as a barrier to entry into the world of writing generic code.
Seems to me that the core of the issue is that the IEEE spec enforces the
observation that `==` is usually the wrong question to ask from a mathematical
PoV when it comes to infinities and NaNs, but we don’t have anything better to
put in its place when we want to ask it anyway from a less rigorous PoV.
What about having `==` return the layman’s answers, and `===` return IEEE's
answer? That way the behavior is the same regardless of generic vs concrete. Or
the other way around, since `===` means “equivalent” / “identical” (I forget
which), which at least to me implies a stronger similarity than just “equals"
(plus, this way wouldn’t be source-breaking). Either way, either behavior is
readily available. And either way, since none of the stdlib numeric types have
reference semantics, we can have them all follow the same pattern WRT “==“ and
“===“. For the integer types, the two operators would be interchangeable, but
it’d allow for generic numeric code that could rely on both operators being
present.
- Dave Sweeris
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution