<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Oct 25, 2017, at 11:22 PM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" class="">xiaodi.wu@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">On Wed, Oct 25, 2017 at 11:46 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="">As someone mentioned earlier, we are trying to square a circle here. We can’t have everything at once… we will have to prioritize.&nbsp; I feel like the precedent in Swift is to prioritize safety/correctness with an option ignore safety and regain speed.<div class=""><br class=""></div><div class="">I think the 3 point solution I proposed is a good compromise that follows that precedent.&nbsp; It does mean that there is, by default, a small performance hit for floats in generic contexts, but in exchange for that, we get increased correctness and safety.&nbsp; This is the exact same tradeoff that Swift makes for optionals!&nbsp; Any speed lost can be regained by providing a specific override for FloatingPoint that uses ‘&amp;==‘.</div></div></blockquote><div class=""><br class=""></div><div class="">My point is not about performance. My point is that `Numeric.==` must continue to have IEEE floating-point semantics for floating-point types and integer semantics for integer types, or else existing uses of `Numeric.==` will break without any way to fix them. The whole point of *having* `Numeric` is to permit such generic algorithms to be written. But since `Numeric.==` *is* `Equatable.==`, we have a large constraint on how the semantics of `==` can be changed.&nbsp;</div></div></div></div></div></blockquote><div><br class=""></div><div>It would also conform to the new protocol and have it’s Equatable conformance depreciated. Once we have conditional conformances, we can add Equatable back conditionally. &nbsp;Also, while we are waiting for that, Numeric can provide overrides of important methods when the conforming type is Equatable or FloatingPoint.</div><div><br class=""></div><br class=""><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="">For example, if someone wants to write a generic function that works both on Integer and FloatingPoint, then they would have to use the new protocol which would force them to correctly handle cases involving NaN.</div></div></blockquote><div class=""><br class=""></div><div class="">What "new protocol" are you referring to, and what do you mean about "correctly handling cases involving NaN"? The existing API of `Numeric` makes it possible to write generic algorithms that accommodate both integer and floating-point types--yes, even if the value is NaN. If you change the definition of `==` or `&lt;`, currently correct generic algorithms that use `Numeric` will start to _incorrectly_ handle NaN.</div></div></div></div></div></blockquote><div><br class=""></div><div><br class=""></div><div>#1 from my previous email (shown again here):</div><div><blockquote type="cite" class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div class="" style="word-wrap: break-word;"><div class=""><div class=""><div class="m_-4014199803616980042h5"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;">Currently, I think we should do 3 things:<br class=""><br class="">1) Create a new protocol with a partial equivalence relation with signature of (T, T)-&gt;Bool? and automatically conform Equatable things to it<br class="">2) Depreciate Float, etc’s… Equatable conformance with a warning that it will eventually be removed (and conform Float, etc… to the partial equivalence protocol)<br class="">3) Provide an '&amp;==‘ relation on Float, etc… (without a protocol) with the native Float IEEE comparison</blockquote></div></div></div></div></blockquote></div></div></div></div></div></div></blockquote></div></div></div></blockquote></div><div><br class=""></div><div>In this case, #2 would also apply to Numeric. &nbsp;You can think of the new protocol as a failable version of Equatable, so in any case where it can’t meet equatable’s rules, it returns nil.</div><div><br class=""></div><br class=""><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="">If speed is super important in that particular case, then they can write overrides for the FloatingPoint case which uses &amp;==, and for Equatable which uses ==.</div><div class=""><br class=""></div><div class="">Because Float’s Equatable conformance is just being depreciated (with a warning/fixit), authors have at least a version to decide whether speed or correctness (or hopefully both) is most important to them.</div></div></blockquote><div class=""><br class=""></div><div class="">My point here is not about generic algorithms written to take any Equatable value; it's about protocol-based numeric algorithms, which we in SE-0104 devoted much time and energy to support in the first place.</div></div></div></div></div></blockquote><div><br class=""></div><div>See above.</div><div><br class=""></div><div>Thanks,</div><div>Jon</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">&nbsp;</div><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 class="">Thanks,</div><div class="">Jon</div><div class=""><br class=""></div><div class="">P.S. We really should not be comparing against the speed of algorithms which don’t correctly handle NaN. Let’s compare Apples to Apples.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Again, what do you mean about "correctly handle NaN"? Most algorithms today *do* correctly handle NaN, in that they are concordant with the IEEE-specified behavior. Set *not* deduplicating NaN *is* correct handling of NaN, for instance, for as long as NaN != NaN.</div><div class=""><br class=""></div><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 class=""><div class="m_-4014199803616980042h5"><div class=""><div class=""><blockquote type="cite" class=""><div class="">On Oct 25, 2017, at 6:36 PM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank" class="">xiaodi.wu@gmail.com</a>&gt; wrote:</div><br class="m_-4014199803616980042m_-6282367460427292267Apple-interchange-newline"><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="">On Wed, Oct 25, 2017 at 8:26 PM, Jonathan Hull<span class="m_-4014199803616980042m_-6282367460427292267Apple-converted-space">&nbsp;</span><span dir="ltr" class="">&lt;<a href="mailto:jhull@gbis.com" target="_blank" class="">jhull@gbis.com</a>&gt;</span><span class="m_-4014199803616980042m_-6282367460427292267Apple-converted-space">&nbsp;</span>wrote:<br class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><span class="">&gt; On Oct 25, 2017, at 9:01 AM, David Sweeris via swift-dev &lt;<a href="mailto:swift-dev@swift.org" target="_blank" class="">swift-dev@swift.org</a>&gt; wrote:<br class="">&gt;<br class="">&gt; That said, I fully acknowledge that this is all above my pay grade (also I hadn't realized that the issue was as settled as it apparently is). If splitting the protocols is a no-go from the get go, I'll go back to trying to figure out a better way to handle it without doing that.<br class=""><br class=""><br class=""></span>I don’t think it is settled.&nbsp; The issue that Xiaodi mentioned was a PartiallyEq protocol which still had a signature of (T,T)-&gt;Bool.&nbsp; People just used that protocol instead of Equatable without taking into account the difference in behavior.&nbsp; The signature of (T,T)-&gt;Bool? changes things because people are forced to deal with the optional.<br class=""><br class="">Currently, I think we should do 3 things:<br class=""><br class="">1) Create a new protocol with a partial equivalence relation with signature of (T, T)-&gt;Bool? and automatically conform Equatable things to it<br class="">2) Depreciate Float, etc’s… Equatable conformance with a warning that it will eventually be removed (and conform Float, etc… to the partial equivalence protocol)<br class="">3) Provide an '&amp;==‘ relation on Float, etc… (without a protocol) with the native Float IEEE comparison<br class=""><br class="">I think this provides several benefits.&nbsp; #3 allows pure speed when needed, but not in a generic context (and is appropriately scary to cause some thought).&nbsp; #1 forces correct handling in generic contexts.&nbsp; #2 gives people time to make the adjustment, but also eventually requires them to switch to using #1 or #3.<br class=""><br class="">I think it will cause A LOT of currently incorrect code to be fixed.<br class=""></blockquote><div class=""><br class=""></div><div class="">One issue which occurred to me only recently, which I hadn't considered, renders my `&amp;==` idea and all similar schemes untenable:</div><div class=""><br class=""></div><div class="">Useful algorithms can and are written which operate on both floating-point and integer numeric types. In fact, the whole point of laboriously designing `Numeric` as part of SE-0104 was to make it possible to do so. If IEEE comparison is relegated to `FloatingPoint` and the only operator remaining on `Numeric` is `==`, then not only will there be a mandatory performance hit, but currently correct algorithms can be broken with absolutely no way to express a fix.</div></div></div></div></div></blockquote></div><br class=""></div></div></div></div></div></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></body></html>