[swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

Jonathan Hull jhull at gbis.com
Wed Jan 17 16:56:04 CST 2018


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.

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 <mailto:xiaodi.wu at gmail.com>> wrote:
> On Tue, Jan 16, 2018 at 4:30 PM, Nevin Brackett-Rozinsky <nevin.brackettrozinsky at gmail.com <mailto: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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20180117/5d9939e6/attachment.html>


More information about the swift-evolution mailing list