<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Oct 26, 2017, at 11:47 AM, Xiaodi Wu via swift-dev &lt;<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">On Thu, Oct 26, 2017 at 1:30 PM, Jonathan Hull <span dir="ltr" class="">&lt;<a href="mailto:jhull@gbis.com" target="_blank" class="">jhull@gbis.com</a>&gt;</span> wrote:<br class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="">Now you are just being rude. We all want Swift to be awesome… let’s try to keep things civil.</div></blockquote><div class=""><br class=""></div><div class="">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:</div><div class=""><br class=""></div><div class="">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?</div><div class=""><br class=""></div><div class="">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?</div></div></div></div></div></blockquote><div><blockquote type="cite" class=""><br class=""></blockquote></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""></div><div class="">You said it was impossible, so I gave you a very quick example showing that the current behavior was still possible.&nbsp; I wasn’t recommending that everyone should only ever use that example for all things.</div><div class=""><br class=""></div><div class="">For FloatingPoint, ‘(a &amp;== b) == true’ would mimic the current behavior (bugs and all). It may not hold for all types.</div></div></blockquote><div class=""><br class=""></div><div class="">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 `&amp;==`.</div></div></div></div></div></blockquote><div><br class=""></div>Would something like this work?</div><div><br class=""></div><div>Numeric.== -&gt; Bool&nbsp;</div><div>traps on NaN etc.</div><div><br class=""></div><div><div>Numeric.==? -&gt; Bool?&nbsp;</div><div>returns nil on NaN etc. You likely don't want this unless you know something about floating-point.</div><div><br class=""></div></div><div>Numeric.&amp;== -&gt; Bool</div><div>is IEEE equality. You should not use this unless you are a floating-point expert.</div><div><br class=""></div><div>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.)</div><div><br class=""></div><div>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.</div><div><br class=""></div><div>Numeric.+ -&gt; T</div><div>traps on FP NaN and integer overflow</div><div><br class=""></div><div>Numeric.+? -&gt; T?</div><div>returns nil on FP NaN and integer overflow</div><div><br class=""></div><div>Numeric.&amp;+ -&gt; T</div><div>performs FP IEEE addition and integer wraparound</div><div><br class=""></div><div><br class=""></div><div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class="">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.<div class=""><br class=""></div><div class="">If you need full performance, then you would have separate overrides on Numeric for members which conform to FloatingPoint (where you could use &amp;==) 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.</div></div></div></blockquote><div class=""><br class=""></div><div class="">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`.</div></div></div></div></div></blockquote><div><br class=""></div><div>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.</div><div><br class=""></div><div>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.</div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">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.</div></div></div></div></div></blockquote><div><br class=""></div><div>I agree that providing a way to get IEEE equality in a generic context is useful. I am not convinced that Numeric.== -&gt; Bool is the right place to provide it.</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">--&nbsp;</div><div class="">Greg Parker &nbsp; &nbsp; <a href="mailto:gparker@apple.com" class="">gparker@apple.com</a>&nbsp; &nbsp; &nbsp;Runtime Wrangler</div><div class=""><br class=""></div><div class=""><br class=""></div></body></html>