<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br></div><div>On Jan 16, 2017, at 13:40, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div dir="ltr">On Mon, Jan 16, 2017 at 12:02 PM, Stephen Canon <span dir="ltr">&lt;<a href="mailto:scanon@apple.com" target="_blank">scanon@apple.com</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><span class="gmail-"><blockquote type="cite">On Jan 16, 2017, at 3:25 AM, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br></blockquote><div><blockquote type="cite"><div><div style="font-family:helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br class="gmail-m_7691912612560415340Apple-interchange-newline">Unless I'm mistaken, after removing division, models of SignedArithmetic would have the mathematical properties of a ring. For every element a in ring R, there must exist an additive inverse -a in R such that a + (-a) = 0. Models of Arithmetic alone would not necessarily have that property.</div></div></blockquote></div><br></span><div>Closure under the arithmetic operations is a sticky point for all the finite integer models vs. the actual ring axioms.&nbsp; No finite [non-modulo] integer type is closed, because of overflow. Similarly, additive inverses don’t exist for the most negative value of a signed type,</div></div></blockquote><div><br></div><div>I think this goes back to the distinct mentioned earlier: imperfection in how we model something, or a difference in what we're modeling? Finite memory will dictate that any model that attempts to represent integers will face constraints. Signed integer types represent a best-effort attempt at exactly representing the greatest possible number of integers within a given amount of memory such that the greatest proportion of those have an additive inverse that can be also be represented in the same amount of memory.</div><div>&nbsp;</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>or for any non-zero value of an unsigned type.</div></div></blockquote><div><br></div><div>This is not fundamentally attributable to a limitation of how we model something. Non-zero values of unsigned type do not have additive inverses in the same way that non-one values of unsigned type do not have multiplicative inverses.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>The obvious way around this is to say that types conforming to Arithmetic model a subset of a ring that need not be closed under the operations.</div></div></blockquote><div><br></div><div>If we don't remove division, type conforming to Arithmetic would also model a subset of a field that need not be closed under the operations. I'm not sure it'd be wise to put such a mathematical definition on it with a "need not" like that. Better, IMO, to give these protocols semantics based on a positive description of the axioms that do hold--with the caveat that the result of addition and multiplication will hold to these axioms only insofar as the result does not overflow.</div></div></div></div></blockquote><br><div>What about writing the division part of the protocol so that the return type isn't necessarily `Self`?</div><div>protocol Arithmetic {</div><div>&nbsp; &nbsp; associatedtype DivisionResult</div><div>&nbsp; &nbsp; // use a function instead of an operator to avoid making this the mother of all breaking changes</div><div>&nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; static func divide (_: Self, _: Self) -&gt; Self.DivisionResult</div><div>&nbsp; &nbsp; ...</div><div>}</div><div>extension FloatingPoint {</div><div>&nbsp; &nbsp; typealias <span style="background-color: rgba(255, 255, 255, 0);">DivisionResult = Self</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">}</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">extension Integer {</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; typealias&nbsp;DivisionResult = (quotient: Self, remainder: Self)</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">}</span></div><div>That way, Integer division returns the "correct" answer regardless of whether the numerator is a multiple of the denominator.</div><div>In generic algorithms, you could easily extract the "normal" value like this:</div><div>&nbsp; &nbsp; let tValue = T.divide(x, y).0</div><div>because the `.0` of a non-tuple value is just the original value, right?</div><div><br></div><div>One thing I'm not sure about (and can't check because I'm not in front of a computer) is how this would affect multiplication... Would we want `Self` and `Self.DivisionResult` to be mutually multipliable?</div><div><div><span style="background-color: rgba(255, 255, 255, 0);">protocol Arithmetic {</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; associatedtype DivisionResult</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; ...</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; static func divide (_: Self, _: Self) -&gt; Self.DivisionResult</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp;&nbsp;static func * (_: Self, _: Self) -&gt; Self</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; static func * (_: Self, _: Self.DivisionResult) -&gt; Self</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; static func * (_:&nbsp;Self.DivisionResult, _: Self) -&gt; Self</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">}</span></div></div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div><span style="background-color: rgba(255, 255, 255, 0);">Could the compiler figure out that,&nbsp;where Self.DivisionResult == Self,&nbsp;those three * functions are actually just one function, or,&nbsp;whenever you tried to actually multiply stuff,&nbsp;would it throw its hands in the air (like it just don't care) and complain about ambiguous references to "*"?</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div><span style="background-color: rgba(255, 255, 255, 0);">- Dave Sweeris</span></div></body></html>