[swift-dev] Rationalizing FloatingPoint conformance to Equatable

David Sweeris davesweeris at mac.com
Fri Oct 27 15:54:57 CDT 2017

> On Oct 27, 2017, at 3:06 AM, Jonathan Hull via swift-dev <swift-dev at swift.org> wrote:
>> On Oct 26, 2017, at 11:44 PM, Xiaodi Wu <xiaodi.wu at gmail.com <mailto:xiaodi.wu at gmail.com>> wrote:
>> On Fri, Oct 27, 2017 at 1:30 AM, Jonathan Hull <jhull at gbis.com <mailto:jhull at gbis.com>> wrote:
>> One completely different idea, which I brought up a year or so ago, is to do what we do with pointers around this.  That is you have your fast/unsafe IEEE Floats/Doubles/etc that have a scarier name.  These do not conform to Equatable or Comparable, but have their own version of IEEE equality/comparison. Let’s spell it &== and &< to make it feel different so the users consider the possibility of NaN.  They don’t have any notion of hashability.
>> As I wrote in my reply to Greg, IEEE equality and comparison is _the_ best approximation of mathematical equality and comparison suitable for floating-point types. If another one were superior, then floating-point experts would have designated that as the standard.
> We definitely have different world views.  I see the handling of NaN as a legacy/compatibility issue due to committee/vendor politics from the 1980’s.  I am pretty sure if they could do it over with modern tech, we would just have isNan() and NaN == NaN… or we might just have optionals instead.

For a sufficiently non-mathematical definition of "logic"...

Logically speaking, NaN == NaN, but mathematically speaking it does not. NaN is, by definition, not a number, so asking if it's equal to itself or anything else is a mathematically meaningless question (same goes for < and >). If you're keeping track of why the answer is NaN, then there's at least a basis for discussing the matter... like in `1.0 == sin(x)/x`, where x is 0... Well, 0/0 is classic example of an undefined result, but the limit of sin(x)/x as x approaches 0 does equal 1, so in some sense -- AFAIK a very non-rigorous sense -- you'd be not entirely wrong to say that `1 == sin(0)/0` could kinda sorta be considered to be "proximately related to `true`" or something. For `==` to know that, though, .nan would need to carry the relevant closure and its arguments as a payload so that some other bits of logic could know how we got to 0/0, and `==` would need in-hardware calculus to verify, in a timely manner, that the limit both exists and is the same from both sides (or I suppose the `/` op could do it... that'd save on the payload requirements, but you're still stuck doing calculus in hardware). Since that's prohibitively impractical, if `==` has to give a boolean answer, it is much more correct to say "NaN != NaN". One could argue that the semantics of Swift's `==` ought be closer to "matches" than "equals", though, which I think is what Xiaodi is getting at.

- Dave Sweeris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20171027/f356a7ad/attachment.html>

More information about the swift-dev mailing list