[swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

Nevin Brackett-Rozinsky nevin.brackettrozinsky at gmail.com
Tue Jan 16 18:20:32 CST 2018


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20180116/edd329a2/attachment.html>


More information about the swift-evolution mailing list