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@swift.org> wrote:
> 
> On Tue, Jan 16, 2018 at 6:31 PM, Xiaodi Wu <xiaodi...@gmail.com 
> <mailto:xiaodi...@gmail.com>> wrote:
> On Tue, Jan 16, 2018 at 4:30 PM, Nevin Brackett-Rozinsky 
> <nevin.brackettrozin...@gmail.com <mailto:nevin.brackettrozin...@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@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to