<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Mar 30, 2017, at 2:56 PM, David Hart via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">The current protocols&nbsp;<code style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(27, 31, 35, 0.0470588); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">ExpressibleByIntegerLiteral</code>&nbsp;and&nbsp;<code style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(27, 31, 35, 0.0470588); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">ExpressibleByFloatLiteral</code>&nbsp;are simple and work well but don't support arbitrary precision literal values. Replacing those protocols is a non-goal as they provide a simple interface for work well for most cases.</p></div></div></div></blockquote><div>Honestly, I don't think I agree with this. I see no particular reason to like our current protocols; they break down as soon as your type gets larger than the largest standard library integer/float type, which undermines one of their main use cases.</div><div><br class=""></div><div>I've been toying with a different approach in my head for a few weeks. The `BinaryInteger` protocol contains the concept of a `words` collection, which expresses any integer type as a collection of `UInt`s containing a signed two's-compliment representation of the integer. That means any `BinaryInteger` already contains code to handle a `words` collection. If we made this more exposed in some way, then `ExpressibleByIntegerLiteral` could leverage that conformance.</div><div><br class=""></div><div>One approach would be to extract the `words` collection into a higher-level protocol:</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>protocol BinaryIntegerSource {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>associatedtype Words: Collection where Iterator.Element == UInt</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>var words: Words { get }</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><br class=""></div><div>Then we could modify `BinaryInteger` to accept this:</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>protocol BinaryInteger: BinaryIntegerSource {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>...</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>init&lt;T&nbsp;:&nbsp;BinaryIntegerSource&gt;(_&nbsp;source: T)</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>...</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><br class=""></div><div>And introduce a new `IntegerLiteral` type which is a `BinaryIntegerSource`, but not a `BinaryInteger` (so you can't do arithmetic with it):</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>struct IntegerLiteral:&nbsp;BinaryIntegerSource&nbsp;{</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>associatedtype Words = …</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>var words: Words { … }</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><br class=""></div><div>And now, you can say something like:</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>struct Int128: ExpressibleByIntegerLiteral {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>fileprivate var _value: DoubleWidth&lt;Int64&gt;</div><div><span class="Apple-tab-span" style="white-space:pre">                </span></div><div><span class="Apple-tab-span" style="white-space:pre">                </span>init(integerLiteral value: IntegerLiteral) {</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>_value = DoubleWidth(value)</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><br class=""></div><div>And everything ought to do what it's supposed to. You could still use a different type if you didn't need anything larger than, say, `Int`. I don't believe this would require any changes to the compiler; `IntegerLiteral` could conform to `_ExpressibleByBuiltinIntegerLiteral`, which would allow it to represent integers up to the current limit of 1024 bits + 1 sign bit.</div><div><br class=""></div><div>(There are a few similar approaches we could take, like exposing an `init(words:)` constructor in `BinaryInteger` and having the `IntegerLiteral` behave as a `Words` collection, but all of them basically involve bootstrapping into `BinaryInteger` through the `Words` type.)</div><div><br class=""></div><div>I *think* that the not-yet-implemented `BinaryFloatingPoint.init&lt;Source:&nbsp;BinaryFloatingPoint&gt;(_&nbsp;value: Source)` initializers could be leveraged in a similar way—create a `BinaryFloatingPointSource` protocol and a `BinaryFloatLiteral` type that conforms to it—but I'm less certain of that because I don't really understand how this universal float conversion is supposed to work. Plus, the universal float conversion is still just a TODO comment right now.</div><div><br class=""></div><div>(This would leave non-binary floats in the lurch, but we're pretty much doing that already—try initializing `Decimal` through its `ExpressibleByFloatLiteral` conformance sometime and you'll see what I mean. I would support changing its name to `ExpressibleByBinaryFloatLiteral`.)</div><div><br class=""></div><div>These leave our current integer and floating-point literal size limits (1025-bit signed integers and 80-bit floats) in place, but those are implementation details and could be changed. In practice, I very much hope the compiler will try to optimize initialization from literals aggressively.</div></div><div><br class=""></div><div class="">
<span class="Apple-style-span" style="border-collapse: separate; font-variant-ligatures: normal; font-variant-east-asian: normal; font-variant-position: normal; line-height: normal; border-spacing: 0px;"><div class=""><div style="font-size: 12px; " class="">--&nbsp;</div><div style="font-size: 12px; " class="">Brent Royal-Gordon</div><div style="font-size: 12px; " class="">Architechies</div></div></span>

</div>
<br class=""></body></html>