> On Apr 18, 2017, at 11:40 AM, Ben Cohen via swift-evolution
> <swift-evolution@swift.org> wrote:
>
>
>> On Apr 17, 2017, at 9:40 PM, Chris Lattner via swift-evolution
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>
>>
>>> On Apr 17, 2017, at 9:07 AM, Joe Groff via swift-evolution
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>
>>>
>>>> On Apr 15, 2017, at 9:49 PM, Xiaodi Wu via swift-evolution
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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.
For what it’s worth, I agree with Ben and Joe; there are some surprises lurking
here, but they are less hazardous to the inexperienced programmer than the
surprises that lurk with any other solution I’ve seen.
– Steve
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution