On Wed, Apr 26, 2017 at 6:23 PM, Michel Fortin <[email protected]> wrote:
> Le 26 avr. 2017 à 18:33, Xiaodi Wu <[email protected]> a écrit : > > On Wed, Apr 26, 2017 at 2:14 PM, Michel Fortin via swift-evolution < > [email protected]> wrote: > >> Just throwing a idea that came to me while reading this discussion >> (hopefully not duplicating something that was already suggested)... >> >> We could introduce `FiniteFloat` and `FiniteDouble` types that would >> disallow NaN and infinity. Computations creating NaN or infinity would trap >> with these types, mimicking what happens with integers in Swift. Converting >> a `Double` to `FiniteDouble` would be achieved through a `finiteValue` >> property like this: >> >> var a = 1.0 >> var b = a.finiteValue! >> >> where the `finiteValue` property returns a `FiniteDouble?` that is `nil` >> for NaN or infinity values. The finite type variant can conform to >> Equatable with no issue. The regular one that allows NaNs and infinity >> would then have less pressure to conform to Equatable. Just request the >> finite value whenever you need it: >> >> dict[a.finiteValue!] = "a" >> >> I understand that this goes a bit beyond solving the problem with >> comparison which is caused by NaNs and not by infinity values. But it's >> quite easy to explain what "finite" means and it follows how integers >> works. It also has the interesting property of guarantying a finite value >> for APIs that needs that, which I believe is more frequent than APIs that >> require only a non-NaN value. Hence why I'm suggesting FiniteDouble and not >> NonNaNDouble. >> > > The issue, here, again is that you're proposing tinkering with Swift > floating point types without addressing the motivations here, which is an > issue with _Comparable_. The problem is that: > > (a) People use arrays of type Float and Double. > > (b) You can invent new ways to represent floating point values, but as > long as you interact with data from anywhere else (not just interoperating > with C or using existing algorithms that make use of floating point > types, but even simply reading in any file that stores floating point data, > since those will be serialized as IEEE floating point values), you _will_ > be using Float and Double. > > (c) People expect to sort and compare arrays of type Float and Double. > > You can introduce a type called DefinitelyNotNaNDouble and then rename > Double to PotentiallyReallyBadNaNDouble, but people will still need to sort > and compare arrays of PotentiallyReallyBadNaNDouble. And after all that > work, you still have not answered the question, how do we write generic > algorithms that (a) use generic comparison; and (b) behave in a sensible > way when working with values of type PotentiallyReallyBadNaNDouble? > > > You are right. I had the dictionary/set problem in mind, but that's not > the one related to `Comparable`. With this design the problem with > `Comparable` would have to be "solved" by making `Double` (the one that > supports NaN) not conform to `Comparable`. Which means that the basic > generic `sort` would not work with a `[Double]`; instead we'd have to write > a more specialized `sort` for that... > > And to write that more specialized `sort` we add a `SometimeComparable` > protocol with the ability to tell when values are unordered and have > `Float` and `Double` conform to it. We could probably make `Comparable` > conform to it automatically. And with that the `sort` for > `SometimeComparable` can also handle the plain `Comparable` and thus > becomes the most generic one. In the end we have two comparable protocols, > one for when things are always comparable and one for when they are only > sometime comparable, and generic algorithms would be free to accept one or > the other depending on whether they can deal with the unordered case or not. > > (We could do the same thing with `Equatable` vs. `SometimeEquatable`. > Generic algorithms would have to choose one or the other in their generic > constraints.) > Right, and this is the solution that Rust uses, but as pointed out in the proposal here, it's been found that this is not a good solution. So, the goal here is a single Equatable and Comparable protocol to which Float and Double conform. Again, the goal is to be able to write generic `sort` with `Double`; we want to make it work correctly, not remove it altogether. Maybe I'm turning in full circle here. There's actually no need for > `FixedDouble` with this, except maybe as a convenience wrapper type to pass > a double to a generic algorithm that can't deal with unordered values. > > -- > Michel Fortin > https://michelf.ca > >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
