> 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

Reply via email to