<div dir="ltr">On Mon, Jan 16, 2017 at 2:04 PM, Dave Abrahams <span dir="ltr">&lt;<a href="mailto:dabrahams@apple.com" target="_blank">dabrahams@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 class="gmail-HOEnZb"><div class="gmail-h5"><br>
on Mon Jan 16 2017, Xiaodi Wu &lt;<a href="http://xiaodi.wu-AT-gmail.com" rel="noreferrer" target="_blank">xiaodi.wu-AT-gmail.com</a>&gt; wrote:<br>
<br>
&gt; On Mon, Jan 16, 2017 at 12:02 PM, Stephen Canon &lt;<a href="mailto:scanon@apple.com">scanon@apple.com</a>&gt; wrote:<br>
&gt;<br>
&gt;&gt; On Jan 16, 2017, at 3:25 AM, Xiaodi Wu via swift-evolution &lt;<br>
&gt;&gt; <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; Unless I&#39;m mistaken, after removing division, models of SignedArithmetic<br>
&gt;&gt; would have the mathematical properties of a ring. For every element a in<br>
&gt;&gt; ring R, there must exist an additive inverse -a in R such that a + (-a) =<br>
&gt;&gt; 0. Models of Arithmetic alone would not necessarily have that property.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; Closure under the arithmetic operations is a sticky point for all the<br>
&gt;&gt; finite integer models vs. the actual ring axioms.  No finite [non-modulo]<br>
&gt;&gt; integer type is closed, because of overflow. Similarly, additive inverses<br>
&gt;&gt; don’t exist for the most negative value of a signed type,<br>
&gt;&gt;<br>
&gt;<br>
&gt; I think this goes back to the distinct mentioned earlier: imperfection in<br>
&gt; how we model something, or a difference in what we&#39;re modeling? Finite<br>
&gt; memory will dictate that any model that attempts to represent integers will<br>
&gt; face constraints. Signed integer types represent a best-effort attempt at<br>
&gt; exactly representing the greatest possible number of integers within a<br>
&gt; given amount of memory such that the greatest proportion of those have an<br>
&gt; additive inverse that can be also be represented in the same amount of<br>
&gt; memory.<br>
&gt;<br>
&gt;&gt; or for any non-zero value of an unsigned type.<br>
&gt;&gt;<br>
&gt;<br>
&gt; This is not fundamentally attributable to a limitation of how we model<br>
&gt; something. Non-zero values of unsigned type do not have additive inverses<br>
&gt; in the same way that non-one values of unsigned type do not have<br>
&gt; multiplicative inverses.<br>
&gt;<br>
&gt; The obvious way around this is to say that types conforming to Arithmetic<br>
&gt;&gt; model a subset of a ring that need not be closed under the operations.<br>
&gt;&gt;<br>
&gt;<br>
&gt; If we don&#39;t remove division, type conforming to Arithmetic would also model<br>
&gt; a subset of a field that need not be closed under the operations. I&#39;m not<br>
&gt; sure it&#39;d be wise to put such a mathematical definition on it with a &quot;need<br>
&gt; not&quot; like that. Better, IMO, to give these protocols semantics based on a<br>
&gt; positive description of the axioms that do hold--with the caveat that the<br>
&gt; result of addition and multiplication will hold to these axioms only<br>
&gt; insofar as the result does not overflow.<br>
<br>
</div></div>I feel like I&#39;m mostly watching from the sidelines as the math titans<br>
duke it out, but, FWIW, that sounds pretty good to me.</blockquote><div><br></div><div>Ha, Steve is the titan. I&#39;m just some guy who&#39;s still trying to wrap his head about this stuff. A few more comments though:</div><div><br></div><div>- Why is `signum` required on BinaryInteger? Should it not be required on SignedArithmetic instead? For signed non-integers, a signum function can be defined. It can even be generalized to complex numbers. I&#39;m unsure, OTOH, what one does with a signum function for an unsigned integer...</div><div><br></div><div>- Why is there a static `isSigned` on BinaryInteger? All types refine either `SignedInteger` or `UnsignedInteger`, which would seem to give you the desired answer either statically or dynamically.</div><div><br></div><div>- A rough sketch of what I understand the semantics to be of these protocols so far: <a href="https://gist.github.com/xwu/a4250536ff8e5d207682079b641e9408">https://gist.github.com/xwu/a4250536ff8e5d207682079b641e9408</a></div><div><br></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"><span class="gmail-HOEnZb"><font color="#888888"><br>
--<br>
-Dave<br>
</font></span></blockquote></div><br></div></div>