[swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

Xiaodi Wu xiaodi.wu at gmail.com
Mon Jan 15 18:41:01 CST 2018


On Mon, Jan 15, 2018 at 4:24 PM, Nevin Brackett-Rozinsky via
swift-evolution <swift-evolution at swift.org> wrote:

> Currently, the FloatingPoint protocol does not conform to
> ExpressibleByFloatLiteral, whereas BinaryFloatingPoint does.
>
> The only explanation I can find for this is a brief comment from Steve
> Canon
> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160425/015691.html>
> during the review of SE-0067 (Enhanced Floating Point Protocols)
> <https://github.com/apple/swift-evolution/blob/master/proposals/0067-floating-point-protocols.md>
> :
>
>
> On Mon, Apr 25, 2016 at 1:32 PM, Stephen Canon via swift-evolution
>> <swift-evolution at swift.org> wrote:
>>
>> On Apr 23, 2016, at 8:53 PM, Brent Royal-Gordon via swift-evolution
>>> <swift-evolution at swift.org> wrote:
>>>
>>> Any reason why FloatLiteralConvertible isn't on FloatingPoint?
>>
>>
>> It doesn’t make sense for non-radix-2 types; you would change bases
>> multiple times.
>
>
>
> I don’t have Steve’s level of floating-point expertise, but from a
> conceptual standpoint Swift protocols encapsulate semantics and, unless I
> am quite mistaken, semantically a floating-point number *can* be expressed
> as a floating-point literal.
>
> So, what exactly is the problem preventing such a conformance, and what
> would be required to fix it? Do we need to revamp how numeric literals are
> handled, eg. to allow arbitrary-precision integers and base-agnostic floats?
>

Note that there are no types that ship with Swift itself that conform to
FloatingPoint but not BinaryFloatingPoint (Foundation.Decimal does not
conform to FloatingPoint, and cannot do so without some major
backwards-incompatible surgery because of how it handles subnormals,
infinity, NaN, and a host of other issues), so this discussion does not
affect most (any?) end users.


The name ExpressibleByFloatLiteral is kind of a misnomer. To conform, a
type must be able to convert a value from some other type that conforms to
_ExpressibleByBuiltinFloatLiteral, which is to say a _binary_
floating-point type.

If you create a Decimal type, it *could try to conform* to
ExpressibleByFloatLiteral, but given `var x: Double = 0.1`, the value would
actually be something like 0.10000000000000001, not exactly 0.1, because
it'd be the decimal approximation of a _binary_ approximation to the
literal. This is what Steve means by "you would change bases multiple
times," and the result is unintuitive. The alternative is to try to convert
to a decimal value via the _string representation_ of the _binary
approximation_ to the literal, which would let you recover `0.1` but lose
all information as to significant digits in the original literal (i.e.,
"0.1" vs. "0.100"), an important piece of information for Decimal types.

In other words, given the actual design of ExpressibleByFloatLiteral, it
doesn't entirely make sense for non-binary floating-point types to conform.


Yes, we can try to perform major surgery on the floating-point literal
protocol, or add another one, so that it's possible for non-binary types to
conform, and there have been proposals on this list along those lines. It
would appear to me that any such design would necessarily be more complex
and possibly slower than the existing design; at its simplest, it could
involve representing the literal as a string, which almost all types,
whether Decimal or BigInt, would expected to be able to parse anyway. But
that's a much larger discussion for another day. The answer to your
question as to why `FloatingPoint` does not refine
`ExpressibleByFloatLiteral` is as shown above; tl;dr: it doesn't make sense
to do so.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20180115/aa84349a/attachment.html>


More information about the swift-evolution mailing list