<div dir="ltr">On Thu, Nov 2, 2017 at 7:10 PM, Stephen Canon <span dir="ltr">&lt;<a href="mailto:scanon@apple.com" target="_blank">scanon@apple.com</a>&gt;</span> wrote:<br><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 style="word-wrap:break-word;line-break:after-white-space"><span class="gmail-">On Nov 2, 2017, at 7:22 PM, Xiaodi Wu via swift-dev &lt;<a href="mailto:swift-dev@swift.org" target="_blank">swift-dev@swift.org</a>&gt; wrote:</span><div><br><div><span class="gmail-"><blockquote type="cite"><div><div dir="ltr">On Thu, Nov 2, 2017 at 5:22 PM, Matthew Johnson <span dir="ltr">&lt;<a href="mailto:matthew@anandabits.com" target="_blank">matthew@anandabits.com</a>&gt;</span> wrote:<br><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><br><div><blockquote type="cite"><span class="gmail-m_5290834492828425647gmail-"><div>On Nov 2, 2017, at 5:20 PM, Jonathan Hull via swift-dev &lt;<a href="mailto:swift-dev@swift.org" target="_blank">swift-dev@swift.org</a>&gt; wrote:</div><br class="gmail-m_5290834492828425647gmail-m_9196866851710290294Apple-interchange-newline"></span><div><div><span class="gmail-m_5290834492828425647gmail-">It looks like we have a good solution.  Per Steve and David’s suggestions:<div><br></div><div>1) Make FloatingPoint == reflexive</div><div><br></div><div>2) Add &amp;== to FloatingPoint for those who specifically want IEEE behavior</div><div><br></div><div>3) Add a warning + fixit to ‘a != a’ </div><div><br></div></span><div>We should take this to evolution…</div></div></div></blockquote><div><br></div>Looks like a winner to me.</div></div></blockquote><div><br></div><div>Again, there remain several problems with this design. In the concrete context, the syntax `&amp;==` suggests that it is a compatibility, legacy, or specialized function not to be preferred over `==`. This makes Swift deviate from every other programming language, creating a new footgun for experienced developers, and encourages a performance hit where one is not demonstrably necessary (most operations that ask about UI coordinates, say, will never have NaN as an input).</div></div></div></div></div></blockquote><div><br></div></span><div>This is a real concern, which I don’t think can be dismissed easily. It’s really the only major concern that I have, however.</div><span class="gmail-"><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>Again also, this design eliminates the possibility of writing a class of useful algorithms that use Numeric. It also doesn&#39;t address the problem of sorting (as NaN would still compare unordered to all other values). These are serious questions that require careful consideration.</div></div></div></div></div></blockquote><div><br></div></span><div>What algorithms do you have in mind? You want to detect and handle NaN for a generic algorithm written against Numeric context via x != x, I assume?</div><div><br></div><div>If we went down the road that I sketched out, I think we would (completely arbitrarily) order NaN after +Inf under Comparable. Anything else would be fairly inconsistent.</div></div></div></div></blockquote><div><br></div><div>This would break generic numerics terribly. Consider the following:</div><div><br></div><div>```</div><div>func f&lt;T : Numeric&gt;(_ value: T) {</div><div>  if value &gt; 0 {</div><div>    // Here, `value` can&#39;t be NaN. If NaN &gt; +Inf, this code is now very broken.</div><div>    // What an easy trap to step into, especially since *no other language* behaves this way.</div><div>    // ...</div><div>  }</div><div>}</div><div>```</div><div><br></div><div>Likewise, any `precondition(value &gt;= 0)`, etc. For the same reason, it&#39;s not merely about using `x != x` in generic code, although that is one use case. Consider:</div><div><br></div><div>```</div><div>func g&lt;T : Numeric&gt;(_ width: T, _ height: T) {</div><div>  if width == height {</div><div>    // Here, neither `width` nor `height` is NaN.</div><div>    // Suppose you&#39;re working with bounding boxes.</div><div>    // Your code can proceed correctly in manipulating a square bounding box.</div><div>    // If NaN == NaN, this code would be broken. A NaN x NaN shape is not a square.</div><div>  }</div><div>}</div><div>```</div><div><br></div><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 style="word-wrap:break-word;line-break:after-white-space"><div><div><div></div><div>Broadly I agree that if we can find some other way to make things work, we should do it, but this also isn’t a *terrible* option.</div><div><br></div><div>– Steve</div></div></div></div></blockquote></div><br></div></div>