> On Oct 26, 2017, at 11:47 AM, Xiaodi Wu via swift-dev <swift-dev@swift.org> 
> wrote:
> 
> On Thu, Oct 26, 2017 at 1:30 PM, Jonathan Hull <jh...@gbis.com 
> <mailto:jh...@gbis.com>> wrote:
> Now you are just being rude. We all want Swift to be awesome… let’s try to 
> keep things civil.
> 
> Sorry if my reply came across that way! That wasn't at all the intention. I 
> really mean to ask you those questions and am interested in the answers:
> 
> Unless I misunderstand, you're arguing that your proposal is superior to 
> Rust's design because of a new operator that returns `Bool?` instead of 
> `Bool`; if so, how is it that you haven't reproduced Rust's design problem, 
> only with the additional syntax involved in unwrapping the result?
> 
> And if, as I understand, your argument is that your design is superior to 
> Rust's *because* it requires unwrapping, then isn't the extent to which 
> people will avoid using the protocol unintentionally also equally and 
> unavoidably the same extent to which it makes Numeric more cumbersome?
> 
> You said it was impossible, so I gave you a very quick example showing that 
> the current behavior was still possible.  I wasn’t recommending that everyone 
> should only ever use that example for all things.
> 
> For FloatingPoint, ‘(a &== b) == true’ would mimic the current behavior (bugs 
> and all). It may not hold for all types.
> 
> No, the question was how it would be possible to have these guarantees hold 
> for `Numeric`, not merely for `FloatingPoint`, as the purpose is to use 
> `Numeric` for generic algorithms. This requires additional semantic 
> guarantees on what you propose to call `&==`.

Would something like this work?

Numeric.== -> Bool 
traps on NaN etc.

Numeric.==? -> Bool? 
returns nil on NaN etc. You likely don't want this unless you know something 
about floating-point.

Numeric.&== -> Bool
is IEEE equality. You should not use this unless you are a floating-point 
expert.

The experts can get high performance or sophisticated numeric behavior. The 
rest of us who naïvely use == get a relatively foolproof floating-point model. 
(There is no difference among these three operators for fixed-size integers, of 
course.)

This is analogous to what Swift does with integer overflow. I would further 
argue the other Numeric operators like + should be extended to the same triple 
of trap or optional or just-do-it. We already have two of those three operators 
for integer addition after all.

Numeric.+ -> T
traps on FP NaN and integer overflow

Numeric.+? -> T?
returns nil on FP NaN and integer overflow

Numeric.&+ -> T
performs FP IEEE addition and integer wraparound


> The whole point is that you have to put thought into how you want to deal 
> with the optional case where the relation’s guarantees have failed.
> 
> If you need full performance, then you would have separate overrides on 
> Numeric for members which conform to FloatingPoint (where you could use &==) 
> and Equatable (where you could use ==). As you get more generic, you lose 
> opportunities for optimization. That is just the nature of generic code. The 
> nice thing about Swift is that you have an opportunity to specialize if you 
> want to optimize more. Once things like conditional conformances come online, 
> all of this will be nicer, of course.
> 
> This is a non-starter then. Protocols must enable useful generic code. What 
> you're basically saying is that you do not intend for it to be possible to 
> use methods on `Numeric` to ask about level 1 equivalence in a way that would 
> not be prohibitively expensive. This, again, eviscerates the purpose of 
> `Numeric`.

I'm not sure that there is a performance problem. If your compiled code is 
actually making calls to generic comparison functions then you have already 
lost the high performance war. Any place where the compiler knows enough to use 
a specialized comparison function should also be a place where the compiler can 
optimize away unnecessary floating-point checks.

Let me make an analogous objection to the current Numerics design. How do you 
get the highest performance addition operator in a generic context? Currently 
you can't, because Numeric.+ checks for integer overflow.


> The point I'm making here, again, is that there are legitimate uses for `==` 
> guaranteeing partial equivalence in the generic context. The approximation 
> being put forward over and over is that generic code always requires full 
> equivalence and concrete floating-point code always requires IEEE partial 
> equivalence. That is _not true_. Some generic code (for instance, that which 
> uses `Numeric`) relies on partial equivalence semantics and some 
> floating-point code can nonetheless benefit from a notion of full equivalence.

I agree that providing a way to get IEEE equality in a generic context is 
useful. I am not convinced that Numeric.== -> Bool is the right place to 
provide it.


-- 
Greg Parker     gpar...@apple.com <mailto:gpar...@apple.com>     Runtime 
Wrangler


_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to