[swift-evolution] [Proposal draft] Enhanced floating-point protocols

Chris Lattner clattner at apple.com
Fri Apr 15 12:49:18 CDT 2016


On Apr 15, 2016, at 8:20 AM, Stephen Canon <scanon at apple.com> wrote:
>> 
>> Incidentally, if you make pi and e be static members of the type, we should get a pretty fluent style, along the lines of:
>> 
>> 	let x = someDouble * 2 * .pi
>> 
>> I agree that there is a concern about deciding “which” constants to include.  I’ll let you and the numeric elite figure that out :-)
> 
> “e” is a great bike-shedding example.  While it would definitely allow a fluent style if you know what you’re looking at, I worry a little bit about readability of `Float.e` or `.e` in source.  Most programmers are at least passingly familiar with pi, but that familiarity doesn’t necessarily extend to e.  IDEs and docstrings make this palatable, of course.
> 
> I wonder if maybe we shouldn’t expose `.pi` directly, but tuck other constants behind something like `.math.e`.

Yes, I think this is a great approach.  In my (totally limited and arbitrary) experience, Pi is used orders of magnitude more commonly than other non-trivial constants.

This is another situation where I wish we had real submodules and generic properties already.  At that point, we could these constants defined in the Math submodule, and even give them unicode aliases like π.  Then you’d get this sort of behavior:

let _ = 2*.pi*b    // works everywhere.
let _ = y + Math.e + .pi  // works everywhere, for all the weird constants you want to dump into the math module.
let _ = 2 * Math.π * b    // works everywhere.

func doMathStuff() {   // some local scode
  import Math
  let _ = y + e + .pi     // works because we imported Math.
  let _ = 2 * π * b        // works because we imported Math.
}

That said, we don’t have those features, so perhaps the discussion should be scoped to just adding the pi member for swift 3.

> The other question is how these play with arbitrary-precision types, if someone wants to write one that conforms to Floating Point.  Usually in arbitrary-precision libraries, these would be functions (desiredPrecision: Int) -> Self, but they could also be implemented as a future that gets evaluated to the desired precision when used or something similar.  If we add these to the protocols, I wouldn’t want to constrain the design space arbitrarily.  The most conservative approach would be to just add them to the concrete types.  We could also put them in a FixedWidthFloatingPoint protocol for now if necessary.

It would be unfortunate if these weren’t supported by (e.g.) the binary FP protocol at least, since that would defeat code trying to use type-generic FP algorithms.

Does the rest of your design scale to arbitrary precision types?  Is arbitrary precision FP used in any common or important domain?  If not, it seems worth throwing under the bus to get better utility for the types that non-specialists actually use in practice. 

-Chris


More information about the swift-evolution mailing list