On Fri, Oct 27, 2017 at 5:06 AM, Jonathan Hull <jh...@gbis.com> wrote:
> > On Oct 26, 2017, at 11:44 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote: > > On Fri, Oct 27, 2017 at 1:30 AM, Jonathan Hull <jh...@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. > > Just to play devil’s advocate, there are actually much better and more > accurate representations available using the same number of bits. The main > issue is that there isn’t common hardware support for them. That is not > what I am suggesting here however. > > > Swift correctly exposes only one concept of equality for floating-point > types. It is and should be IEEE equality. People should be encouraged and > not scared to use it. NaN is and should continue to exist as a concept. > Yes, IEEE-compliant floating point is hard; the only thing harder than > IEEE-compliant floating point is non-IEEE-compliant floating point. > > > What I am suggesting is identical to IEEE in every way except for NaN. > The most recent edition of IEEE 754 is 70 pages long and mentions NaN on 40 of them. What you suggest is not an IEEE-compliant design for floating point. > It is just an IEEE value that has been filtered so that we can guarantee > it isn’t NaN. It still uses all the same hardware instructions. Basically, > it semantically converts NaN to nil… and that lets us conform to > Equatable/Comparable honestly. It also still technically adheres to IEEE… > it just never comes up because we are careful to filter/handle NaN before > the user ever has to deal with it. > > If you want/need to use NaN for some reason, you still have the IEEE > types. What you can’t do is use them generically for ==. > > Can you give me an example of where you would want NaN in a generic > context (that might also contain Ints), but an optional Float (which had > been filtered not to have NaN) wouldn’t meet your needs? Remember, this is > a generic context, not one that is special casing Floats. > I'm not sure I understand the question. If you've already filtered out NaN values, then you wouldn't have any NaN values, so why would you need a generic algorithm that handles NaN? > This thread is meant to discuss how to reconcile this scenario with the > semantics of Equatable. > > > Yes it is… and this is one possible approach to doing it. We make it so > Floats just don’t conform to Equatable, but we make a wrapper type that > does conform (and can fully meet the guarantees). > > > > Then you have your safe/friendly Swift Floating point type(s) which just >> have no concept of NaN at all (and probably a single notion of zero). You >> have a failable initializer from the IEEE versions. These types conform to >> Equatable/Hashable/Comparable. Care is taken with internal methods so >> that NaN can’t creep into the type. >> >> How do we handle math functions which might fail? We do the same thing >> we do in the rest of Swift... those functions return an optional. >> >> When reading in data from the outside world or C code, you would use the >> IEEE versions and then either convert or do your calculations directly. >> They would probably also be used for things like accelerate. But most >> code, where the values come from user input or literals, would never even >> have to touch the IEEE version. >> >> The advantage here is that you get full speed all the time, even in >> generic contexts. You just can’t use the IEEE versions directly in generic >> contexts. You would have to convert them, which is a one-time cost (or use >> them non-generically). >> > > Again, generics and protocol-based numerics are important; that's what > Numeric is all about. Any idea that doesn't make this possible is a > non-starter. > > > Why is everything “impossible” or a “non-starter”? > To have a focused discussion, we have to define the givens and the task to be accomplished. Here, the given constraint is that Swift floating point types are IEEE-compliant and conform to Equatable. The task is to design Equatable. The wrapper version would adhere to Numeric and would be fully usable in > generic contexts. You can wrap the IEEE Floats, and the NaNs get converted > to optionals, where you can apply the generic algorithm. If your “generic” > algorithm was depending on the bit representation of NaN or the fact that > it breaks ==, then I would argue you really don’t want a generic algorithm > after all… you have a Float specific algorithm. > > Also, in terms of speed, we should find something with the semantics we > want (that should be the main focus of our discussion)… and then we can > figure out how to tweak it so it goes as fast as we need it to once we know > what we are aiming for. Anything else is premature optimization. >
_______________________________________________ swift-dev mailing list swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev