<div>On Mon, Jan 15, 2018 at 19:20 Nevin Brackett-Rozinsky <<a href="mailto:nevin.brackettrozinsky@gmail.com">nevin.brackettrozinsky@gmail.com</a>> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>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?</div></div></blockquote><div dir="auto"><br></div><div dir="auto">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.</div><div dir="auto"><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div></div><div>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.</div></div></blockquote><div dir="auto"><br></div><div dir="auto">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.</div><div dir="auto"><br></div><div dir="auto">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.</div><div dir="auto"><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div></div></div></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>In any case, is this something that would have to be done before ABI stability, or could it wait until after?</div></div></blockquote><div dir="auto"><br></div><div dir="auto">I don’t think the current protocol can go away, so any additions or enhancements are something that can wait.</div><div dir="auto"><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div></div></div></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>Nevin</div></div><div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jan 15, 2018 at 7:41 PM, Xiaodi Wu <span><<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><span>On Mon, Jan 15, 2018 at 4:24 PM, Nevin Brackett-Rozinsky via swift-evolution <span><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br></span><div class="gmail_extra"><div class="gmail_quote"><span><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div>Currently, the FloatingPoint protocol does not conform to ExpressibleByFloatLiteral, whereas BinaryFloatingPoint does.<div><br></div><div>The only explanation I can find for this is a <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160425/015691.html" target="_blank">brief comment from Steve Canon</a> during the review of <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0067-floating-point-protocols.md" target="_blank">SE-0067 (Enhanced Floating Point Protocols)</a>:</div><div><br></div><div><br></div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">On Mon, Apr 25, 2016 at 1:32 PM, Stephen Canon via swift-evolution <swift-evolution at <a href="http://swift.org" target="_blank">swift.org</a>> wrote:<br><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">On Apr 23, 2016, at 8:53 PM, Brent Royal-Gordon via swift-evolution <swift-evolution at <a href="http://swift.org" target="_blank">swift.org</a>> wrote:<br><br>Any reason why FloatLiteralConvertible isn't on FloatingPoint?</blockquote><br>It doesn’t make sense for non-radix-2 types; you would change bases multiple times.</blockquote></div><div><br></div><div><br></div><div>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.</div><div><br></div><div>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?</div></div></blockquote><div> </div></span><div>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.</div><div><br></div><div><br></div><div>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.</div><div><br></div><div>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.10000000000000001, 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.</div><div><br></div><div>In other words, given the actual design of ExpressibleByFloatLiteral, it doesn't entirely make sense for non-binary floating-point types to conform.</div><div><br></div><div><br></div><div>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.</div><div><br></div></div></div></div>
</blockquote></div><br></div></div></blockquote></div></div>