[swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

Xiaodi Wu xiaodi.wu at gmail.com
Tue Jan 16 17:31:50 CST 2018


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?


Of course, “T: FloatingPoint” is an overconstraint in this example, as what
> I actually want is “T: OrderedField”
>

This approach was considered during revision of integer protocols and
rejected. You could make your own protocol to which your types of interest
then conform, if you're so interested.


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.


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
}


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
}


On Tue, Jan 16, 2018 at 3:39 PM, Chris Lattner <clattner at nondot.org> wrote:
>
>> On Jan 15, 2018, at 11:01 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution at swift.org> wrote:
>> > - Can we change the semantics? Maybe, but I doubt
>> ExpressibleByFloatLiteral can be outright replaced. You're not the first to
>> wonder about how to design an alternative protocol. Dig through the
>> archives and you'll find some existing ideas. My two cents: The main
>> alternative base in question here is 10. However, decimal storage formats
>> and binary storage formats share so little in common that any initializer
>> common to both will be extremely unwieldy for one or both formats.
>> Personally, somewhere down the road, I'd rather see Decimal64/128 become
>> standard library types (already working on it), DecimalFloatingPoint become
>> a standard library protocol, and `0.1` become a "decimal literal" (with
>> Float, Double, Float80, and Decimal64/128 all conforming) as distinct from
>> a "float literal" that we could then restrict to hexadecimal (?and binary)
>> floating-point literals (and maybe rename accordingly).
>>
>> If we were motivated to fix this (and I’m not :-), then I think the best
>> path forward would be to rename ExpressibleByFloatLiteral to something like
>> ExpressibleByBinaryFloatLiteral.  This would allow the introduction of a
>> new ExpressibleByDecimalFloatLiteral with a different initializer
>> requirement.
>>
>> I’m not motivated to fix this, because there is nothing actively broken
>> by the current state of things.  With the current name we can still
>> introduce a ExpressibleByDecimalFloatLiteral someday in the future.  The
>> two names will be a little odd, but given the cost of changing it at this
>> point, that seems perfectly acceptable.
>>
>> -Chris
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20180116/ae74514f/attachment.html>


More information about the swift-evolution mailing list