[swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

Xiaodi Wu xiaodi.wu at gmail.com
Wed Jan 17 18:48:43 CST 2018


On Wed, Jan 17, 2018 at 4:56 PM, Jonathan Hull via swift-evolution <
swift-evolution at swift.org> wrote:

> I’m with Nevin on this one.  Perhaps the easiest thing to do is to add
> something to the FloatLiteral type that lets you get it as a string if
> desired.
>
> Didn’t we have a discussion a while back on how to make Integer Literals
> work with BigInt?  Maybe there is an idea from that discussion that would
> help.
>
> Tl;dr:  Literals shouldn’t be tied to a particular implementation of a
> single conforming type (though they can/should be optimized for common
> implementations).  The issue here is that FloatLiteral is throwing out
> information which is given to it based on its underlying implementation.  I
> view this as a bug.
>

I suppose you can view it as anything you want; but the initial question
was whether there is a reason that FloatingPoint doesn't conform to
ExpressibleByFloatLiteral, and there very much is: namely, the current
semantics of a float literal.

Literals aren't tied to any particular conforming type, but they are always
tied to some group of built-in types. Until there's a clear additional use
case (e.g., a Decimal type), it's pretty pointless to redesign literal
protocols, because whether or not a particular way in which information
about the literal value is conveyed to the initializer is ergonomic and
efficient will depend on the underlying implementation of the type.

BigInt will be able to take advantage, in the next version of Swift, to
DoubleWidth's conformance to _ExpressibleByBuiltinIntegerLiteral; in other
words, literals of up to 2048 bits are supported, and that's plenty for a
literal.


> Thanks,
> Jon
>
>
>
> On Jan 16, 2018, at 4:20 PM, Nevin Brackett-Rozinsky via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> On Tue, Jan 16, 2018 at 6:31 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
>> On Tue, Jan 16, 2018 at 4:30 PM, Nevin Brackett-Rozinsky <
>> nevin.brackettrozinsky at gmail.com> wrote:
>>
>>> The thing that is “broken” here is generic programming. If I constrain
>>> something to FloatingPoint, I cannot use a float literal in calculations
>>> with it:
>>>
>>> func centimeters<T: FloatingPoint> (inches: T) -> T {
>>>     return 2.54 * inches    // Error
>>>
>>> }
>>>
>>
>> Why not constrain it to `BinaryFloatingPoint`? What other types are you
>> trying to use with this function?
>>
>
> We should not ask nor expect people to constrain their generic algorithms
> to BinaryFloatingPoint unless they are working with the radix.
>
>
>
>> so that eg. a Rational type could be used. And that gives a hint as to
>>> the workaround:
>>>
>>> func centimeters<T: FloatingPoint> (inches: T) -> T {
>>>     return (254 / 100) * inches
>>> }
>>>
>>
>> Yes, you *could* do that.
>>
>
> And it seems I *will* be doing that, as long as such a workaround is
> necessary. Though it does appear to have the unfortunate cost of an extra
> division operation.
>
>
> That only works for numbers which don’t overflow the integer literals
>>> though.
>>>
>>
>> Integer literals don't overflow until 2048 bits. The following compiles
>> just fine:
>>
>> func moles<T : FloatingPoint>(particles: T) -> T {
>>   let N_A: T = 602_214_085_774_000_000_000_000
>>   return particles / N_A
>> }
>>
>
> When I write that in a playground it shows N_A as 1.67866967797794e+18.
>
> (Also, you appear to have mistakenly concatenated the standard uncertainty
> in the last 2 digits, “74”, onto the accepted value for the constant.)
>
>
> If we want a really large or small value then we have to split it in
>>> pieces:
>>>
>>> func moles <T: FloatingPoint> (particles: T) -> T {
>>>     let avogadroNumber: T = 6_022_140_857 * 100_000_000_000_000
>>>     return particles / avogadroNumber
>>>
>>> }
>>>
>>> It would be much nicer to write “let avogadroNumber: T = 6.022140857e23”.
>>>
>>
>> You could write:
>>
>> func moles<T : FloatingPoint & LosslessStringConvertible>(particles: T)
>> -> T {
>>   let N_A = T("6.02214085774e+23")!
>>   return particles / N_A
>> }
>>
>
> …or I could write “T: FloatingPoint & ExpressibleByFloatLiteral”. I could
> even make a typealias for that. But I shouldn’t have to.
>
> Nevin
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20180117/70d77a14/attachment.html>


More information about the swift-evolution mailing list