Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-17 Thread Xiaodi Wu via swift-evolution
On Wed, Jan 17, 2018 at 4:56 PM, Jonathan Hull via swift-evolution <
swift-evolution@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@swift.org> wrote:
>
> On Tue, Jan 16, 2018 at 6:31 PM, Xiaodi Wu  wrote:
>
>> On Tue, Jan 16, 2018 at 4:30 PM, Nevin Brackett-Rozinsky <
>> 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 (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 (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(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  (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(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
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-17 Thread Jonathan Hull via swift-evolution
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 
>  wrote:
> 
> On Tue, Jan 16, 2018 at 6:31 PM, Xiaodi Wu  > wrote:
> On Tue, Jan 16, 2018 at 4:30 PM, Nevin Brackett-Rozinsky 
> > 
> 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 (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 (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(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  (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(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


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-16 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 16, 2018 at 6:20 PM, Nevin Brackett-Rozinsky <
nevin.brackettrozin...@gmail.com> wrote:

> On Tue, Jan 16, 2018 at 6:31 PM, Xiaodi Wu  wrote:
>
>> On Tue, Jan 16, 2018 at 4:30 PM, Nevin Brackett-Rozinsky <
>> 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 (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.
>

On the contrary, I think the "currency" floating-point protocol should be
`BinaryFloatingPoint`. Having worked with `FloatingPoint` rather
extensively (or, attempted to at least), I reiterate that I find it to be a
distinctly unhelpful protocol in terms of enabling useful generic
algorithms; if we were to do anything, I'd advocate for its complete
removal before ABI stability sets in. For compatibility we would supply a
deprecated `typealias FloatingPoint = BinaryFloatingPoint`.



>
>> so that eg. a Rational type could be used. And that gives a hint as to
>>> the workaround:
>>>
>>> func centimeters (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.
>

There should be no runtime cost when specialized.


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(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.)
>

Yes, those are typos; I was typing freehand into an email. Please adjust
the number and value of digits as necessary.



> If we want a really large or small value then we have to split it in
>>> pieces:
>>>
>>> func moles  (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(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.
>

Sure, you could do that too. Your solution here is actually probably the
best, in that if a user wishes to conform a decimal type
to ExpressibleByFloatLiteral, your extensions would also work for that
type. I've already explained why the semantics of ExpressibleByFloatLiteral
are such that not every FloatingPoint type could conform.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-16 Thread Nevin Brackett-Rozinsky via swift-evolution
On Tue, Jan 16, 2018 at 6:31 PM, Xiaodi Wu  wrote:

> On Tue, Jan 16, 2018 at 4:30 PM, Nevin Brackett-Rozinsky <
> 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 (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 (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(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  (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(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


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-16 Thread Rick Mann via swift-evolution


> On Jan 16, 2018, at 15:32 , Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On Jan 16, 2018, at 14:30 , Nevin Brackett-Rozinsky via swift-evolution 
>  wrote:
>> 
>> That only works for numbers which don’t overflow the integer literals 
>> though. If we want a really large or small value then we have to split it in 
>> pieces:
>> 
>> func moles  (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(particles: T) -> T {
>   let N_A = T("6.02214085774e+23")!
>   return particles / N_A
> }

You're not seriously proposing this alternative, are you? I'm with Nevin on 
this: “let avogadroNumber: T = 6.022140857e23”.


-- 
Rick Mann
rm...@latencyzero.com


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


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-16 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 16, 2018 at 4:30 PM, Nevin Brackett-Rozinsky <
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 (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 (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(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  (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(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  wrote:
>
>> On Jan 15, 2018, at 11:01 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution@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
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-16 Thread Nevin Brackett-Rozinsky via swift-evolution
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 (inches: T) -> T {

return 2.54 * inches// Error

}

Of course, “T: FloatingPoint” is an overconstraint in this example, as what
I actually want is “T: OrderedField” so that eg. a Rational type could be
used. And that gives a hint as to the workaround:

func centimeters (inches: T) -> T {

return (254 / 100) * inches

}

That only works for numbers which don’t overflow the integer literals
though. If we want a really large or small value then we have to split it
in pieces:

func moles  (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”.

Nevin


On Tue, Jan 16, 2018 at 3:39 PM, Chris Lattner  wrote:

> On Jan 15, 2018, at 11:01 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@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
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-16 Thread Chris Lattner via swift-evolution
On Jan 15, 2018, at 11:01 PM, Xiaodi Wu via swift-evolution 
 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


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


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-15 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 16, 2018 at 00:32 Nevin Brackett-Rozinsky <
nevin.brackettrozin...@gmail.com> wrote:

> On Mon, Jan 15, 2018 at 11:27 PM, Xiaodi Wu  wrote:
>
>> On Mon, Jan 15, 2018 at 20:37 Nevin Brackett-Rozinsky <
>> nevin.brackettrozin...@gmail.com> wrote:
>>
>>>
>>> That protocol is spelled ExpressibleByFloatLiteral, which reflects the
>>> meaning that we want and should have. The name is correct, the problem is
>>> with the implementation.
>>>
>>
>> I get that you want float literals to have semantics other than what they
>> have. Again, that's a different conversation.
>>
>
> It is the exact conversation I started this thread to have, so if there is
> any other conversation going on here then *that* is the different one. :-)
>

There are two distinct questions here:

- Your original questions to the list. Rephrased: Is it an implementation
bug that FloatingPoint does not refine ExpressibleByFloatLiteral? Can
FloatingPoint, with its current semantics, refine
ExpressibleByFloatLiteral, with its current semantics? The answer is: no
and no.

- 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).
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-15 Thread Nevin Brackett-Rozinsky via swift-evolution
On Mon, Jan 15, 2018 at 11:27 PM, Xiaodi Wu  wrote:

> On Mon, Jan 15, 2018 at 20:37 Nevin Brackett-Rozinsky <
> nevin.brackettrozin...@gmail.com> wrote:
>
>>
>> That protocol is spelled ExpressibleByFloatLiteral, which reflects the
>> meaning that we want and should have. The name is correct, the problem is
>> with the implementation.
>>
>
> I get that you want float literals to have semantics other than what they
> have. Again, that's a different conversation.
>

It is the exact conversation I started this thread to have, so if there is
any other conversation going on here then *that* is the different one. :-)

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


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-15 Thread Xiaodi Wu via swift-evolution
On Mon, Jan 15, 2018 at 20:37 Nevin Brackett-Rozinsky <
nevin.brackettrozin...@gmail.com> wrote:

> On Mon, Jan 15, 2018 at 8:51 PM, Xiaodi Wu  wrote:
>
>> On Mon, Jan 15, 2018 at 19:20 Nevin Brackett-Rozinsky <
>> nevin.brackettrozin...@gmail.com> wrote:
>>
>>> All I’m saying is the current situation seems semantically wrong. As in,
>>> how can a type claim to be a floating point number, if it *literally*
>>> cannot be represented by a floating point number?
>>>
>>
>> Again, you can think of it that way, but what I’m saying is that
>> “FloatLiteral” is a misnomer: semantically, a conforming type is
>> specifically claiming that it is expressible by a _binary_ floating point
>> number.
>>
>
>  I strongly disagree. To say that it is a “misnomer” implies that the
> semantics are correct and the problem is with the name.
>
> However, in Swift a floating point literal consists of certain patterns of
> characters in source code, as specified by the language grammar. Thus it is
> meaningful and correct to say that certain types can be expressed as
> floating point literals. We have a protocol for exactly that purpose: to
> indicate that conforming types can be written as floating point literals.
>

I understand that you disagree with the current semantics, but they aren't
arbitrary. You know, I’m sure, that we can write integer literals in any of
several bases. For example, `0x` is an integer literal which represents
the same value as `65535`:

  0x == 65535 // true

It doesn’t matter in which base you write the literal, it represents some
particular _binary integer_ up to a maximum of 2048 (binary) digits.

Likewise, we can write floating-point literals in any of several bases. For
example:

  0x1.5bf0a8b145769p1 == 2.7182818284590451 // true

It doesn't matter in which base you write the literal, it represents some
particular _binary floating-point value_ up to a maximum of 63 or 52
fractional bits, depending on the platform.

That protocol is spelled ExpressibleByFloatLiteral, which reflects the
> meaning that we want and should have. The name is correct, the problem is
> with the implementation.
>

I get that you want float literals to have semantics other than what they
have. Again, that's a different conversation. I'm simply explaining that
the current semantics are not by accident, and that the implementation
isn't a buggy execution of the semantics you think they should have, but an
exact execution of semantics you may not agree with but nonetheless
deliberately chosen.

If you want to argue that, after we fix the buggy implementation of
> ExpressibleByFloatLiteral, then we should introduce a new protocol named
> ExpressibleByBinaryFloatLiteral, that might be a discussion worth having.
> But for the existing protocol, renaming it would not solve the underlying
> issue.
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-15 Thread Nevin Brackett-Rozinsky via swift-evolution
On Mon, Jan 15, 2018 at 8:51 PM, Xiaodi Wu  wrote:

> On Mon, Jan 15, 2018 at 19:20 Nevin Brackett-Rozinsky <
> nevin.brackettrozin...@gmail.com> wrote:
>
>> All I’m saying is the current situation seems semantically wrong. As in,
>> how can a type claim to be a floating point number, if it *literally*
>> cannot be represented by a floating point number?
>>
>
> Again, you can think of it that way, but what I’m saying is that
> “FloatLiteral” is a misnomer: semantically, a conforming type is
> specifically claiming that it is expressible by a _binary_ floating point
> number.
>

 I strongly disagree. To say that it is a “misnomer” implies that the
semantics are correct and the problem is with the name.

However, in Swift a floating point literal consists of certain patterns of
characters in source code, as specified by the language grammar. Thus it is
meaningful and correct to say that certain types can be expressed as
floating point literals. We have a protocol for exactly that purpose: to
indicate that conforming types can be written as floating point literals.

That protocol is spelled ExpressibleByFloatLiteral, which reflects the
meaning that we want and should have. The name is correct, the problem is
with the implementation.

If you want to argue that, after we fix the buggy implementation of
ExpressibleByFloatLiteral, then we should introduce a new protocol named
ExpressibleByBinaryFloatLiteral, that might be a discussion worth having.
But for the existing protocol, renaming it would not solve the underlying
issue.

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


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-15 Thread Xiaodi Wu via swift-evolution
On Mon, Jan 15, 2018 at 19:20 Nevin Brackett-Rozinsky <
nevin.brackettrozin...@gmail.com> wrote:

> All I’m saying is the current situation seems semantically wrong. As in,
> how can a type claim to be a floating point number, if it *literally*
> cannot be represented by a floating point number?
>

Again, you can think of it that way, but what I’m saying is that
“FloatLiteral” is a misnomer: semantically, a conforming type is
specifically claiming that it is expressible by a _binary_ floating point
number.

You suggest treating a float literal as a string, but another alternative
> is to teach the compiler to handle arbitrary-length integer literals, and
> then treat a float literal as two integer literals separated by a dot.
>

You *could*, but the fractional part is encoded quite differently from the
integral part in a binary floating point value, so that would require an
inelegant conversion.

More elegantly, you could represent the literal as a fraction, where the
denominator is given as a power of the radix. There are many ways to slice
it but this is getting far afield of your original question, which is,
essentially, that given the semantics of the two protocols it’s not correct
to conform FloatingPoint to ExpressibleByFloatLiteral, and not an oversight.

In any case, is this something that would have to be done before ABI
> stability, or could it wait until after?
>

I don’t think the current protocol can go away, so any additions or
enhancements are something that can wait.

Nevin
>
>
> On Mon, Jan 15, 2018 at 7:41 PM, Xiaodi Wu  wrote:
>
>> On Mon, Jan 15, 2018 at 4:24 PM, Nevin Brackett-Rozinsky via
>> swift-evolution  wrote:
>>
>>> Currently, the FloatingPoint protocol does not conform to
>>> ExpressibleByFloatLiteral, whereas BinaryFloatingPoint does.
>>>
>>> The only explanation I can find for this is a brief comment from Steve
>>> Canon
>>> 
>>> during the review of SE-0067 (Enhanced Floating Point Protocols)
>>> 
>>> :
>>>
>>>
>>> On Mon, Apr 25, 2016 at 1:32 PM, Stephen Canon via swift-evolution
  wrote:

 On Apr 23, 2016, at 8:53 PM, Brent Royal-Gordon via swift-evolution
>  wrote:
>
> Any reason why FloatLiteralConvertible isn't on FloatingPoint?


 It doesn’t make sense for non-radix-2 types; you would change bases
 multiple times.
>>>
>>>
>>>
>>> I don’t have Steve’s level of floating-point expertise, but from a
>>> conceptual standpoint Swift protocols encapsulate semantics and, unless I
>>> am quite mistaken, semantically a floating-point number *can* be expressed
>>> as a floating-point literal.
>>>
>>> So, what exactly is the problem preventing such a conformance, and what
>>> would be required to fix it? Do we need to revamp how numeric literals are
>>> handled, eg. to allow arbitrary-precision integers and base-agnostic floats?
>>>
>>
>> Note that there are no types that ship with Swift itself that conform to
>> FloatingPoint but not BinaryFloatingPoint (Foundation.Decimal does not
>> conform to FloatingPoint, and cannot do so without some major
>> backwards-incompatible surgery because of how it handles subnormals,
>> infinity, NaN, and a host of other issues), so this discussion does not
>> affect most (any?) end users.
>>
>>
>> The name ExpressibleByFloatLiteral is kind of a misnomer. To conform, a
>> type must be able to convert a value from some other type that conforms to
>> _ExpressibleByBuiltinFloatLiteral, which is to say a _binary_
>> floating-point type.
>>
>> If you create a Decimal type, it *could try to conform* to
>> ExpressibleByFloatLiteral, but given `var x: Double = 0.1`, the value would
>> actually be something like 0.10001, not exactly 0.1, because
>> it'd be the decimal approximation of a _binary_ approximation to the
>> literal. This is what Steve means by "you would change bases multiple
>> times," and the result is unintuitive. The alternative is to try to convert
>> to a decimal value via the _string representation_ of the _binary
>> approximation_ to the literal, which would let you recover `0.1` but lose
>> all information as to significant digits in the original literal (i.e.,
>> "0.1" vs. "0.100"), an important piece of information for Decimal types.
>>
>> In other words, given the actual design of ExpressibleByFloatLiteral, it
>> doesn't entirely make sense for non-binary floating-point types to conform.
>>
>>
>> Yes, we can try to perform major surgery on the floating-point literal
>> protocol, or add another one, so that it's possible for non-binary types to
>> conform, and there have been proposals on this list along those lines. It
>> would appear to me that any such design would necessarily be more complex
>> and possibly slower than the existing design; at its 

Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-15 Thread Nevin Brackett-Rozinsky via swift-evolution
All I’m saying is the current situation seems semantically wrong. As in,
how can a type claim to be a floating point number, if it *literally*
cannot be represented by a floating point number?

You suggest treating a float literal as a string, but another alternative
is to teach the compiler to handle arbitrary-length integer literals, and
then treat a float literal as two integer literals separated by a dot.

In any case, is this something that would have to be done before ABI
stability, or could it wait until after?

Nevin


On Mon, Jan 15, 2018 at 7:41 PM, Xiaodi Wu  wrote:

> On Mon, Jan 15, 2018 at 4:24 PM, Nevin Brackett-Rozinsky via
> swift-evolution  wrote:
>
>> Currently, the FloatingPoint protocol does not conform to
>> ExpressibleByFloatLiteral, whereas BinaryFloatingPoint does.
>>
>> The only explanation I can find for this is a brief comment from Steve
>> Canon
>> 
>> during the review of SE-0067 (Enhanced Floating Point Protocols)
>> 
>> :
>>
>>
>> On Mon, Apr 25, 2016 at 1:32 PM, Stephen Canon via swift-evolution
>>>  wrote:
>>>
>>> On Apr 23, 2016, at 8:53 PM, Brent Royal-Gordon via swift-evolution
  wrote:

 Any reason why FloatLiteralConvertible isn't on FloatingPoint?
>>>
>>>
>>> It doesn’t make sense for non-radix-2 types; you would change bases
>>> multiple times.
>>
>>
>>
>> I don’t have Steve’s level of floating-point expertise, but from a
>> conceptual standpoint Swift protocols encapsulate semantics and, unless I
>> am quite mistaken, semantically a floating-point number *can* be expressed
>> as a floating-point literal.
>>
>> So, what exactly is the problem preventing such a conformance, and what
>> would be required to fix it? Do we need to revamp how numeric literals are
>> handled, eg. to allow arbitrary-precision integers and base-agnostic floats?
>>
>
> Note that there are no types that ship with Swift itself that conform to
> FloatingPoint but not BinaryFloatingPoint (Foundation.Decimal does not
> conform to FloatingPoint, and cannot do so without some major
> backwards-incompatible surgery because of how it handles subnormals,
> infinity, NaN, and a host of other issues), so this discussion does not
> affect most (any?) end users.
>
>
> The name ExpressibleByFloatLiteral is kind of a misnomer. To conform, a
> type must be able to convert a value from some other type that conforms to _
> ExpressibleByBuiltinFloatLiteral, which is to say a _binary_
> floating-point type.
>
> If you create a Decimal type, it *could try to conform* to
> ExpressibleByFloatLiteral, but given `var x: Double = 0.1`, the value would
> actually be something like 0.10001, not exactly 0.1, because
> it'd be the decimal approximation of a _binary_ approximation to the
> literal. This is what Steve means by "you would change bases multiple
> times," and the result is unintuitive. The alternative is to try to convert
> to a decimal value via the _string representation_ of the _binary
> approximation_ to the literal, which would let you recover `0.1` but lose
> all information as to significant digits in the original literal (i.e.,
> "0.1" vs. "0.100"), an important piece of information for Decimal types.
>
> In other words, given the actual design of ExpressibleByFloatLiteral, it
> doesn't entirely make sense for non-binary floating-point types to conform.
>
>
> Yes, we can try to perform major surgery on the floating-point literal
> protocol, or add another one, so that it's possible for non-binary types to
> conform, and there have been proposals on this list along those lines. It
> would appear to me that any such design would necessarily be more complex
> and possibly slower than the existing design; at its simplest, it could
> involve representing the literal as a string, which almost all types,
> whether Decimal or BigInt, would expected to be able to parse anyway. But
> that's a much larger discussion for another day. The answer to your
> question as to why `FloatingPoint` does not refine
> `ExpressibleByFloatLiteral` is as shown above; tl;dr: it doesn't make sense
> to do so.
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-15 Thread Xiaodi Wu via swift-evolution
On Mon, Jan 15, 2018 at 4:24 PM, Nevin Brackett-Rozinsky via
swift-evolution  wrote:

> Currently, the FloatingPoint protocol does not conform to
> ExpressibleByFloatLiteral, whereas BinaryFloatingPoint does.
>
> The only explanation I can find for this is a brief comment from Steve
> Canon
> 
> during the review of SE-0067 (Enhanced Floating Point Protocols)
> 
> :
>
>
> On Mon, Apr 25, 2016 at 1:32 PM, Stephen Canon via swift-evolution
>>  wrote:
>>
>> On Apr 23, 2016, at 8:53 PM, Brent Royal-Gordon via swift-evolution
>>>  wrote:
>>>
>>> Any reason why FloatLiteralConvertible isn't on FloatingPoint?
>>
>>
>> It doesn’t make sense for non-radix-2 types; you would change bases
>> multiple times.
>
>
>
> I don’t have Steve’s level of floating-point expertise, but from a
> conceptual standpoint Swift protocols encapsulate semantics and, unless I
> am quite mistaken, semantically a floating-point number *can* be expressed
> as a floating-point literal.
>
> So, what exactly is the problem preventing such a conformance, and what
> would be required to fix it? Do we need to revamp how numeric literals are
> handled, eg. to allow arbitrary-precision integers and base-agnostic floats?
>

Note that there are no types that ship with Swift itself that conform to
FloatingPoint but not BinaryFloatingPoint (Foundation.Decimal does not
conform to FloatingPoint, and cannot do so without some major
backwards-incompatible surgery because of how it handles subnormals,
infinity, NaN, and a host of other issues), so this discussion does not
affect most (any?) end users.


The name ExpressibleByFloatLiteral is kind of a misnomer. To conform, a
type must be able to convert a value from some other type that conforms to
_ExpressibleByBuiltinFloatLiteral, which is to say a _binary_
floating-point type.

If you create a Decimal type, it *could try to conform* to
ExpressibleByFloatLiteral, but given `var x: Double = 0.1`, the value would
actually be something like 0.10001, not exactly 0.1, because
it'd be the decimal approximation of a _binary_ approximation to the
literal. This is what Steve means by "you would change bases multiple
times," and the result is unintuitive. The alternative is to try to convert
to a decimal value via the _string representation_ of the _binary
approximation_ to the literal, which would let you recover `0.1` but lose
all information as to significant digits in the original literal (i.e.,
"0.1" vs. "0.100"), an important piece of information for Decimal types.

In other words, given the actual design of ExpressibleByFloatLiteral, it
doesn't entirely make sense for non-binary floating-point types to conform.


Yes, we can try to perform major surgery on the floating-point literal
protocol, or add another one, so that it's possible for non-binary types to
conform, and there have been proposals on this list along those lines. It
would appear to me that any such design would necessarily be more complex
and possibly slower than the existing design; at its simplest, it could
involve representing the literal as a string, which almost all types,
whether Decimal or BigInt, would expected to be able to parse anyway. But
that's a much larger discussion for another day. The answer to your
question as to why `FloatingPoint` does not refine
`ExpressibleByFloatLiteral` is as shown above; tl;dr: it doesn't make sense
to do so.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution