on Sat Apr 22 2017, Chris Lattner <clattner-AT-nondot.org> wrote: > On Apr 22, 2017, at 6:06 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote: >> but my quick reaction to `&==` is that it would make me quite >> nervous to have `==` not bound to 754-equals as it is in essentially >> every other language. In particular, I worry about the risk of >> people porting numerical code that depends on isnan(x) <—> !(x < y) >> in non-obvious ways that they are unlikely to test. I’ll try to > >> follow up with more detailed thoughts tomorrow. >> >> Indeed, it makes me a little nervous too. That said, `==` being >> either bound or not bound to 754 depending on the context is what >> makes me even more nervous. >> >> I was once adamantly against a new spelling for `==`, but on >> reconsideration it's clear to me that few if any numerical recipes >> can be ported verbatim from C-like languages and we should probably >> not encourage people to do so. Already, `+` needs to be rewritten as >> `&+`, `<<` probably should be rewritten as `&<<` (I still haven't >> had enough time to think about this), and the bitwise operators have >> differing precedences that require careful proofreading. > > I haven’t been following this proposal or discussion closely, but it > seems to me that there are a few workable approaches with different > tradeoffs:
Hey Chris, thanks for chiming in. This is interesting, but I need a bit more information to be able to evaluate it: > 1. The strictly correct but user hostile approach: > > * == and != are tied to the Equatable protocol, which is essentially the == > operation. Whose semantics requirements are...? > * <, <=, >, >= are tied to the Comparable protocol, which is essentially the > <=> operation. Whose semantics requirements are...? > * Hashable doesn’t require equatable, it requires a related StrictlyEquatable > protocol. Whose semantics requirements are...? > * StrictlyEquatable refines Equatable (with no other requirements, it > is just a marker protocol), Marker for what? Surely there are stronger semantic requirements? IMO there are probablby useful ways to introduce tighter requirements, e.g. by forcing an optional-returning method to non-optional (roughly Xiaodi's idea). > in which case FP types can’t conform to it, and thus can’t participate > as dictionary keys > > => This approach sucks because you can’t have Set<Float>, or > Dictionary<Float, String>. > > 2. The strictly correct but somewhat user hostile approach: > > * == and != are tied to the Equatable protocol, which is essentially the == > operation. > * <, <=, >, >= are tied to the Comparable protocol, which is essentially the > <=> operation. > * Hashable doesn’t require equatable, it requires a related StrictlyEquatable > protocol. > * StrictlyEquatable doesn’t refine Equatable: it has a different > requirement, and FP types can therefore implement both Equatable and > StrictlyEquatable. Again, I want to understand the semantic requirements of these protocols, and also how they impact the documentation of generic algorithms. > => This approach is suboptimal because implementing your own type > requires you to implement the <=> operation, as well as the > StrictlyEquatable protocol, both. > > 3. The user friendly but incorrect model: > > * == and != are tied to the Equatable protocol, which is essentially the == > operation. > * <, <=, >, >= are tied to the Comparable protocol, which is essentially the > <=> operation. > * Hashable is defined in terms of Equatable. > > => This is easy (types just have to define <=>), but fails for FP types. How so, specifically? I'm not sure how you think these operations would behave for FP. > I don’t think that this proposal is acceptable as written. I wouldn't be happy with accepting it in this form either. Discussions have raised some serious questions for which I don't think we have clear answers. However, there is yet hope that we will find them here :-) > I think it is really bad that abstracting a concrete algorithm would > change its behavior so substantially. I don’t care about SNaNs, but I > do care about the difference between +0/-1 That reads like you're saying you want +0.0 == -0.0 to be false, but I suspect what you really mean is not that there should be no difference in the result +0.0 == -0.0 regardless of context. Am I reading that correctly? Making +0.0 == -0.0 true in all contexts would be an easy change to the proposal and probably the right move, but I think there are other serious issues that I'm not sure we've solved yet. > and secondarily that of NaN handling. It seems really bad that > generalizing something like: > > func doThing(a : Double, b : Double) -> Bool { > …. > return a != b > } > > to: > > func doThing<T : FloatingPoint> (a : T, b : T) -> Bool { > …. > return a != b > } > > would change behavior (e.g. when a is -0.0 and b is +0.0). Again, it wouldn't... > Likewise, "T : Equatable". ...but that one would. -- -Dave _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution