<div dir="ltr">Hi all,<div><br></div><div>I promised some time ago to provide some thoughts based on the experience of using the newly revised integer protocols. I've finally synthesized these thoughts into one document. It is somewhat long, and for that I apologize. I hope that it is at least clear in terms of how it lays out the issues.</div><div><br></div><div>Gist: <a href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2">https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2</a></div><div><br></div><div>Text:</div><div><br></div><div><h1 style="box-sizing:border-box;margin:0px 0px 16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);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'">Notes on the user experience of new integer protocols</h1><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">Xiaodi Wu<br style="box-sizing:border-box">June 17, 2017</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);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'"><a id="gmail-user-content-introduction" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#introduction" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Introduction</h2><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">The design, re-design, and implementation of <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none">SE-0104</a>, a proposal to revise integer protocols in Swift, is now largely complete in shipping previews of Swift 4. As an exercise, I have used the new APIs to develop a <a href="https://github.com/xwu/NumericAnnex" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none">set of additional numeric facilities</a>. Here are some insights gained from that experience--and from two unpublished exercises to implement a BigInt type (one from scratch, one wrapping GMP)--as well as suggestions for improvement.</p><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;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'"><a id="gmail-user-content-topics" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#topics" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Topics</h3><ol style="box-sizing:border-box;padding-left:2em;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"><li style="box-sizing:border-box">Performing heterogeneous comparison with integer literals</li><li style="box-sizing:border-box;margin-top:0.25em">Conforming to <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">_ExpressibleByBuiltinIntegerLiteral</code></li><li style="box-sizing:border-box;margin-top:0.25em">Overriding implementations of heterogeneous comparison and bit shift operators</li><li style="box-sizing:border-box;margin-top:0.25em">Defining the semantics of masking shifts for arbitrary-precision integers</li><li style="box-sizing:border-box;margin-top:0.25em">Using <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">ArithmeticOverflow</code></li><li style="box-sizing:border-box;margin-top:0.25em">Initializing integers from a floating-point source</li></ol><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);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'"><a id="gmail-user-content-heterogeneous-comparison-with-integer-literals" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#heterogeneous-comparison-with-integer-literals" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Heterogeneous comparison with integer literals</h2><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">SE-0104 added heterogeneous comparison and bit shift operators to the language to improve the user experience (for example, you can now check if an <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">Int</code> value is equal to a <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">UInt</code> value).<span style="box-sizing:border-box;font-size:12px;line-height:0;vertical-align:baseline"><a href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#fn1" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none">1</a></span></p><blockquote style="box-sizing:border-box;margin:0px 0px 16px;padding:0px 1em;color:rgb(106,115,125);border-left-width:0.25em;border-left-style:solid;border-left-color:rgb(223,226,229);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px"><p style="box-sizing:border-box;margin-top:0px;margin-bottom:0px"><span id="gmail-user-content-fn1" style="box-sizing:border-box;font-size:12px;line-height:0;vertical-align:baseline">1</span> Similar enhancements for operations such as addition are not yet possible because a design is lacking for how to express <em style="box-sizing:border-box">promotion</em>. When (if) Swift allows integer constants in generic constraints, this may become a more realistic prospect as promotion would then be expressible using generic constraints (e.g. <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">func + <T, U>(lhs: T, rhs: U) -> U where T : FixedWidthInteger, U : FixedWidthInteger, T.BitWidth < U.BitWidth</code>). This is meant to be an aside and is certainly outside the scope of correcting or incrementally improving upon SE-0104.</p></blockquote><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">These operators behave as intended with concrete types, but comparisons in generic algorithms behave differently. This was encountered during review of the standard library's implementation of <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">DoubleWidth</code>, which in fact had a bug as a consequence of the following behavior:</p><div class="gmail-highlight gmail-highlight-source-swift" style="box-sizing:border-box;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"><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(246,248,250);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal"><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">f</span>() <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Bool</span> {
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">return</span> <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">UInt</span>.<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">max</span> <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">==</span> <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">~</span><span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">0</span>
}
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">g</span>() <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Bool</span> {
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">return</span> <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">UInt</span>.<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">max</span> <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">==</span> .<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">max</span>
}
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">h</span><<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">T</span> : <span class="gmail-pl-e" style="box-sizing:border-box;color:rgb(111,66,193)">FixedWidthInteger</span>>(<span class="gmail-pl-smi" style="box-sizing:border-box"><span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">_</span></span>: T.<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">Type</span>) <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Bool</span> {
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">return</span> T.<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">max</span> <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">==</span> <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">~</span><span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">0</span>
}
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">i</span><<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">T</span> : <span class="gmail-pl-e" style="box-sizing:border-box;color:rgb(111,66,193)">FixedWidthInteger</span>>(<span class="gmail-pl-smi" style="box-sizing:border-box"><span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">_</span></span>: T.<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">Type</span>) <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Bool</span> {
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">return</span> T.<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">max</span> <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">==</span> .<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">max</span>
}
<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">f</span>() <span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"><span class="gmail-pl-c" style="box-sizing:border-box">//</span> Returns `true`.</span>
<span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"></span><span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">g</span>() <span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"><span class="gmail-pl-c" style="box-sizing:border-box">//</span> Returns `true`.</span>
<span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"></span><span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">h</span>(<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">UInt</span>.<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">self</span>) <span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"><span class="gmail-pl-c" style="box-sizing:border-box">//</span> Returns `false`.</span>
<span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"></span><span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">i</span>(<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">UInt</span>.<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">self</span>) <span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"><span class="gmail-pl-c" style="box-sizing:border-box">//</span> Returns `true`.</span></pre></div><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">The reason that <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">h(_:)</code> gives a surprising result is explained as follows:</p><ul style="box-sizing:border-box;padding-left:2em;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"><li style="box-sizing:border-box"><p style="box-sizing:border-box;margin-top:16px;margin-bottom:16px">Each concrete integer type implements its own overload of the homogeneous comparison operator, whereas protocol extension methods implement heterogeneous comparison operators. When an integer literal is used on the right-hand side of the comparison, the compiler looks first to the concrete type for an suitable implementation of the operator and finds the homogeneous overload. Therefore, it does <em style="box-sizing:border-box">not</em> traverse the protocol hierarchy and instead infers the literal to be of the same type as the left-hand side.</p></li><li style="box-sizing:border-box;margin-top:0.25em"><p style="box-sizing:border-box;margin-top:16px;margin-bottom:16px">In generic code, <em style="box-sizing:border-box">even if</em> the most refined protocol implements its own overload of the homogeneous comparison operator, the compiler will look for all overloads of the operator by traversing the entire protocol hierarchy. Since heterogeneous comparison operators are defined somewhere along the hierarchy, the compiler will <em style="box-sizing:border-box">always</em> find an overload that accepts the "preferred" integer literal type (<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">Swift.IntegerLiteralType</code>, aka <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">Int</code>) and infers the literal to be of type <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">Int</code>.</p></li></ul><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">Therefore, in the invocation <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">h(UInt.self)</code>, we are actually comparing <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">UInt.max</code> to <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">~(0 as Int)</code>. This is a surprising result, as evidenced by the fact that a bug nearly slipped into the standard library itself.</p><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;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'"><a id="gmail-user-content-suggestion-for-improvement" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#suggestion-for-improvement" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Suggestion for improvement</h3><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">Based on the demonstration that the expression <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">T.max == .max</code> infers the correct type in both concrete and generic code, I would suggest that type inference for integer literals be changed based on the following (notional) rule:</p><ul style="box-sizing:border-box;padding-left:2em;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"><li style="box-sizing:border-box"><span style="box-sizing:border-box;font-weight:600">Any use of an integer literal <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">x</code> should be equivalent to the use of an implicit member expression <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">.init(integerLiteral: x)</code>.</span></li></ul><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">This generally preserves the current behavior that an integer literal will preferentially be inferred to be of type <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">IntegerLiteralType</code>:</p><div class="gmail-highlight gmail-highlight-source-swift" style="box-sizing:border-box;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"><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(246,248,250);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal"><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">j</span>(<span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">_</span> <span class="gmail-pl-smi" style="box-sizing:border-box">x</span>: <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Int</span>) {
<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">print</span>(<span class="gmail-pl-s" style="box-sizing:border-box;color:rgb(3,47,98)"><span class="gmail-pl-pds" style="box-sizing:border-box">"</span>Int<span class="gmail-pl-pds" style="box-sizing:border-box">"</span></span>, x)
}
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">j</span>(<span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">_</span> <span class="gmail-pl-smi" style="box-sizing:border-box">x</span>: <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">UInt</span>) {
<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">print</span>(<span class="gmail-pl-s" style="box-sizing:border-box;color:rgb(3,47,98)"><span class="gmail-pl-pds" style="box-sizing:border-box">"</span>UInt<span class="gmail-pl-pds" style="box-sizing:border-box">"</span></span>, x)
}
<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">j</span>(<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">42</span>) <span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"><span class="gmail-pl-c" style="box-sizing:border-box">//</span> Prints "Int 42".</span>
<span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"></span><span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">j</span>(.<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">init</span>(<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">integerLiteral</span>: <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">42</span>)) <span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"><span class="gmail-pl-c" style="box-sizing:border-box">//</span> Prints "Int 42".</span></pre></div><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">Intriguingly, <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">T.init(integerLiteral: 0)</code> is currently ambiguous where <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">T : FixedWidthInteger</code>, suggesting that some re-design of the protocol would also be necessary to have this rule give the appropriate behavior.</p><div class="gmail-highlight gmail-highlight-source-swift" style="box-sizing:border-box;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"><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(246,248,250);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal"><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">k</span><<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">T</span> : <span class="gmail-pl-e" style="box-sizing:border-box;color:rgb(111,66,193)">FixedWidthInteger</span>>(<span class="gmail-pl-smi" style="box-sizing:border-box"><span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">_</span></span>: T.<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">Type</span>) <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Bool</span> {
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">return</span> (<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">0</span> <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">as</span> T) <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">==</span> T.<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">init</span>(<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">integerLiteral</span>: <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">0</span>)
<span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"><span class="gmail-pl-c" style="box-sizing:border-box">//</span> error: ambiguous reference to member 'init(integerLiteral:)'</span>
<span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"></span>}</pre></div><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);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'"><a id="gmail-user-content-_expressiblebybuiltinintegerliteral" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#_expressiblebybuiltinintegerliteral" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a><code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:inherit;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">_ExpressibleByBuiltinIntegerLiteral</code></h2><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">For a numeric type modeling rational numbers, it is natural to conform that type to <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">ExpressibleByIntegerLiteral</code>. For instance, <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">let x = 42 as Rational</code> would create an instance of <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">Rational<Int></code> with numerator <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">42</code> and denominator <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">1</code>. A similar line of reasoning applies to a numeric type modeling complex numbers (and likely other types as well).</p><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">To conform to the protocol <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">ExpressibleByIntegerLiteral</code>, the type must implement an initializer of the form <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">init(integerLiteral: U)</code>. However, <span style="box-sizing:border-box;font-weight:600"><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">U</code> must conform to an underscored protocol <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">_ExpressibleByBuiltinIntegerLiteral</code></span>.</p><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">For a type such as <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">Rational<T></code>, where the numerator and denominator are of type <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">T</code>, it is natural to have this initializer take an integer literal of type <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">T</code>. Currently, therefore, this requires that <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">T</code> be constrained to an underscored protocol. This is suboptimal for two reasons: (1) <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">_ExpressibleByBuiltinIntegerLiteral</code> is an underscored protocol not meant for public use; (2) it prevents an implementation of <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">Rational<T> where T : _ExpressibleByBuiltinIntegerLiteral</code> from having, say, arbitrary-precision integers as numerator and denominator (i.e., <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">Rational<BigInt></code>) unless the arbitrary-precision integer type itself conforms to <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">_ExpressibleByBuiltinIntegerLiteral</code>.</p><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;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'"><a id="gmail-user-content-suggestion-for-improvement-1" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#suggestion-for-improvement-1" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Suggestion for improvement</h3><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">From a user perspective, the semantics of <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">ExpressibleByIntegerLiteral</code> suggest that a generic type that has exclusively stored properties of type <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">T where T : ExpressibleByIntegerLiteral</code> should be conformable to <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">ExpressibleByIntegerLiteral</code> by implementing an initializer that accepts a literal value of type <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">T</code>--without being constrained to any underscored protocol. I suspect, however, that this is not a trivial detail to implement in the compiler.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);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'"><a id="gmail-user-content-implementations-of-heterogeneous-comparison-and-bit-shift-operators" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#implementations-of-heterogeneous-comparison-and-bit-shift-operators" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Implementations of heterogeneous comparison and bit shift operators</h2><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">In Swift, there is a distinction between <span style="box-sizing:border-box;font-weight:600">default implementations</span> of protocol requirements and <span style="box-sizing:border-box;font-weight:600">protocol extension methods</span> which are not requirements. Both are defined in extensions to protocols, but default implementations are dynamically dispatched and can be overridden by conforming types, while extension methods can be shadowed but never overridden. (For example, homogeneous <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">==</code> is a protocol requirement of <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">Equatable</code>, but homogeneous <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">!=</code> is a protocol extension method that cannot be overridden.)</p><blockquote style="box-sizing:border-box;margin:0px 0px 16px;padding:0px 1em;color:rgb(106,115,125);border-left-width:0.25em;border-left-style:solid;border-left-color:rgb(223,226,229);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px"><p style="box-sizing:border-box;margin-top:0px;margin-bottom:0px">The paragraph above is meant to provide some background on existing features of the language, but it is meant neither to question their existence in the language nor to question the design of <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">Equatable</code> and <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">Comparable</code>, which are far outside the scope of improving the revised integer protocols.</p></blockquote><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">The heterogeneous comparison and bit shift operators introduced in Swift 4 by SE-0104 are <span style="box-sizing:border-box;font-weight:600">protocol extension methods</span>.</p><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">Consider a custom <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">BigInt</code> type and the comparison <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">(42 as BigInt) == (21 as UInt)</code>. There is an efficient way to perform that comparison which does not involve first converting the <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">UInt</code> value to a <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">BigInt</code> value. However, even if <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">BigInt</code> manually implements this specialized comparison operator, a generic algorithm implemented for all binary integers (say, for integer exponentiation) will use the less efficient standard library implementation of heterogeneous <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">==</code>. By contrast, the same algorithm will use the most specialized implementation of homogeneous <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">==</code>, because that function is a protocol requirement that is dynamically dispatched.</p><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;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'"><a id="gmail-user-content-suggestion-for-improvement-2" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#suggestion-for-improvement-2" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Suggestion for improvement</h3><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">Heterogeneous <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"><</code>, <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"><=</code>, <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">==</code>, <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">></code>, <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">>=</code> should be requirements of the protocol on which they are now extension methods, as should heterogeneous masking shifts. That would permit conforming types to provide more specialized implementations. This may, however, increase the work of the type checker at compile time.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);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'"><a id="gmail-user-content-semantics-of-masking-shifts-for-arbitrary-precision-integers" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#semantics-of-masking-shifts-for-arbitrary-precision-integers" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Semantics of masking shifts for arbitrary-precision integers</h2><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">SE-0104 introduced two different types of bit shift operations for integers, called <span style="box-sizing:border-box;font-weight:600">masking shifts</span> and <span style="box-sizing:border-box;font-weight:600">smart shifts</span>.</p><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">Smart shifts, spelled <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"><<</code> and <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">>></code>, are protocol extension methods that always behave in a well-defined way when overshifting or undershifting. For example, <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">x << -2</code> is now equivalent to <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">x >> 2</code> in Swift 4, where previously the behavior was undefined.</p><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">However, because there is sometimes a performance cost for branches that handle overshifting and undershifting that cannot be optimized away, Swift now offers masking shifts, spelled <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">&<<</code> and <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">&>></code>. As explained in SE-0104, "[a] masking shift logically preprocesses the right[-]hand operand by masking its bits to produce a value in the range <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">0...(x-1)</code> where <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">x</code> is the number of bits in the left[-]hand operand." These semantics for masking shifts make sense when the number of bits in the left-hand operand is fixed, as is the case for all fixed-width integers.</p><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">However, <em style="box-sizing:border-box">all</em> binary integers must implement <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">&<<</code> and <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">&>></code>. For an arbitrary-width integer type (which, for various reasons, are best represented as sign-and-magnitude rather than two's-complement), the literal interpretation of those semantics is problematic. For example, most users might think that <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">(1 as BigInt) << 1000</code> should not result in overshift. However, the number of bits in the left-hand operand is 2, and therefore a plausible interpretation of the semantics of <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">&<<</code> would have <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">(1 as BigInt) &<< 1000 == 1</code>. By extension, therefore, <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">(1 as BigInt) << 1000 == 0</code>; this is a counterintuitive result.</p><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;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'"><a id="gmail-user-content-suggestion-for-improvement-3" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#suggestion-for-improvement-3" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Suggestion for improvement</h3><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">The semantics of smart shift should be clarified to state that the right-hand operand is preprocessed by masking its bits to produce a value in the range <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">0..<x</code> where <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">x</code> is the <span style="box-sizing:border-box;font-weight:600">maximum</span> number of bits in a value of the same type as the left-hand operand. This is equivalent to viewing arbitrary-width integers <em style="box-sizing:border-box">for the purposes of bitwise operations</em> as notionally infinite sequences of bits sign-extended from the two's-complement representation of the integral value.</p><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">For the purposes of implementation, <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">BinaryInteger</code> may require a new static property <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">maxBitWidth</code>, which would be equal to <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">bitWidth</code> for fixed-width integers and could be defined as <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">Int.max</code> for arbitrary-precision integers.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);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'"><a id="gmail-user-content-arithmeticoverflow" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#arithmeticoverflow" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a><code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:inherit;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">ArithmeticOverflow</code></h2><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">With SE-0104, the <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">addWithOverflow</code> family of arithmetic operations are not longer <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">static</code>. They have been renamed <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">addingReportingOverflow</code> and the like, and their return type has been changed from <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">(T, Bool)</code> to <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">(partialValue: T, overflow: ArithmeticOverflow)</code>. <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">ArithmeticOverflow</code> is an enum with two cases, <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">overflow</code> and <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">none</code>. Initially, this may appear to be an improvement in terms of readability.</p><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">However, in actual use, <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">ArithmeticOverflow</code> is extremely lacking in ergonomics. Where previously it was possible to destructure the tuple and evaluate overflow by writing <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">if overflow { ... }</code>, it is now required to use a much more verbose incantation: <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">if overflow == .overflow { ... }</code>. There is little else one can do with an <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">ArithmeticOverflow</code> result besides converting it into a value of type <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">Bool</code>. When working with these operations repeatedly--and, chances are that if you need such an operation, you don't need it just once--this quickly becomes very cumbersome.</p><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">Inside the standard library, the <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">ArithmeticOverflow</code> values returned from <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">*ReportingOverflow</code> functions are created by calling an initializer that takes a <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">Bool</code> argument. Therefore, with every call to a <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">*ReportingOverflow</code> function, a <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">Bool</code> is converted to an <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">ArithmeticOverflow</code>, returned, then converted by the user back into a <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">Bool</code>. Worse, based on comments in the standard library, it appears that the compiler cannot currently elide these operations.</p><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;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'"><a id="gmail-user-content-suggestions-for-improvement" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#suggestions-for-improvement" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Suggestions for improvement</h3><ol style="box-sizing:border-box;padding-left:2em;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"><li style="box-sizing:border-box"><p style="box-sizing:border-box;margin-top:16px;margin-bottom:16px">Change the return type of <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">*ReportingOverflow</code> functions to <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">(partialValue: T, overflow: Bool)</code> (or, <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">didOverflow</code>) and eliminate the <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">ArithmeticOverflow</code> type. In practice, this would require deprecating the current functions and providing new overloads.</p></li><li style="box-sizing:border-box;margin-top:0.25em"><p style="box-sizing:border-box;margin-top:16px;margin-bottom:16px">Since the presence of type inference may cause (1) to be source-breaking even with proper deprecations, avoid creating a source-breaking change by naming the revised functions something else. Specifically, take the opportunity to improve the name of these functions, changing <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">addingReportingOverflow</code> to <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">addingWithOverflowReporting</code> (<em style="box-sizing:border-box">mutatis mutandis</em> for the remaining functions). This avoids the "-ing -ing" clash and eliminates the nonsensical interpretation of the phrase "adding, reporting overflow by 42."</p></li></ol><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);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'"><a id="gmail-user-content-integers-from-a-floating-point-source" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#integers-from-a-floating-point-source" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Integers from a floating-point source</h2><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">The new <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">BinaryInteger</code> protocol has the following requirements:</p><ul style="box-sizing:border-box;padding-left:2em;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"><li style="box-sizing:border-box"><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">init?<T : FloatingPoint>(exactly source: T)</code></li><li style="box-sizing:border-box;margin-top:0.25em"><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">init<T : FloatingPoint>(_ source: T)</code></li></ul><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">However, in my experience, it does not appear possible (or at least, it is not apparent even after some careful thought) how to implement these requirement solely with the properties and methods required by <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">FloatingPoint</code>. There do, however, exist straightforward ways to convert <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">BinaryFloatingPoint</code> values to <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">BinaryInteger</code> values.</p><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">In the standard library, concrete integer types implement conversions to and from concrete built-in floating-point types. However, whether coincidentally or not, the standard library itself has not yet implemented these protocol requirements. At last check, the entire implementation of the first requirement was:</p><div class="gmail-highlight gmail-highlight-source-swift" style="box-sizing:border-box;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"><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(246,248,250);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal"> <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">public</span> <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">init?</span><<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">T</span> : <span class="gmail-pl-e" style="box-sizing:border-box;color:rgb(111,66,193)"><span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">FloatingPoint</span></span>>(<span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">exactly</span> <span class="gmail-pl-smi" style="box-sizing:border-box">source</span>: T) {
<span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"><span class="gmail-pl-c" style="box-sizing:border-box">//</span> FIXME(integers): implement</span>
<span class="gmail-pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"></span> <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">fatalError</span>()
}</pre></div><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;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'"><a id="gmail-user-content-suggestions-for-improvement-1" class="gmail-anchor" href="https://gist.github.com/xwu/d68baefaae9e9291d2e65bd12ad51be2#suggestions-for-improvement-1" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Suggestions for improvement</h3><p style="box-sizing:border-box;margin-top:0px;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;margin-bottom:0px">Consider changing the protocol requirement so that <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">T</code> is constrained as follows: <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">T : BinaryFloatingPoint</code>.</p></div></div>