<div dir="ltr"><div>Nice analysis!</div><div><br></div><div>Over what scope should programmers pick between Gábor's 3 categories?</div><div><br></div><div>The "wraparound is desired" category should only occur in narrow parts of code, like computing a hash. That suits a wraparound-operator better than a wraparound-type, and certainly better than a compiler switch. And it doesn't make sense for a type like 'int' that doesn't have a fixed size.</div>
<div><br></div><div>The "wraparound is undesired but performance is critical" category occurs in the most performance critical bits of code [I'm doubting that all parts of all Rust programs are performance critical], and programmers need to make the trade-off over that limited scope. Maybe via operators or types, but not by a compiler switch over whole compilation units.</div>
<div><br></div><div>That leaves "wraparound is undesired and performance is not critical" category for everything else. The choice between checked vs. unbounded sounds like typing.</div><div><br></div><div>BigUint is weird: It can underflow but not overflow. When you use its value in a more bounded way you'll need to bounds-check it then, whether it can go negative or not. Wouldn't it be easier to discard it than squeeze it into the wraparound or checked models?</div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jun 18, 2014 at 11:21 AM, Brian Anderson <span dir="ltr"><<a href="mailto:banderson@mozilla.com" target="_blank">banderson@mozilla.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class=""><br>
On 06/18/2014 10:08 AM, Gábor Lehel wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
# Checked math<br>
<br>
For (2), the standard library offers checked math in the `CheckedAdd`, `CheckedMul` etc. traits, as well as integer types of unbounded size: `BigInt` and `BigUint`. This is good, but it's not enough. The acid test has to be whether for non-performance-critical code, people are actually *using* checked math. If they're not, then we've failed.<br>

<br>
`CheckedAdd` and co. are important to have for flexibility, but they're far too unwieldy for general use. People aren't going to write `.checked_add(2).unwrap()` when they can write `+ 2`. A more adequate design might be something like this:<br>

<br>
 * Have traits for all the arithmetic operations for both checking on overflow and for wrapping around on overflow, e.g. `CheckedAdd` (as now), `WrappingAdd`, `CheckedSub`, `WrappingSub`, and so on.<br>
<br>
 * Offer convenience methods for the Checked traits which perform `unwrap()` automatically.<br>
<br>
 * Have separate sets of integer types which check for overflow and which wrap around on overflow. Whatever they're called: `CheckedU8`, `checked::u8`, `uc8`, ...<br>
<br>
 * Both sets of types implement all of the Checked* and Wrapping* traits. You can use explicit calls to get either behavior with either types.<br>
<br>
 * The checked types use the Checked traits to implement the operator overloads (`Add`, Mul`, etc.), while the wrapping types use the Wrapping traits to implement them. In other words, the difference between the types is (probably only) in the behavior of the operators.<br>

<br>
 * `BigInt` also implements all of the Wrapping and Checked traits: because overflow never happens, it can claim to do anything if it "does happen". `BigUint` implements all of them except for the Wrapping traits which may underflow, such as `WrappingSub`, because it has nowhere to wrap around to.<br>

<br>
Another option would be to have just one set of types but two sets of operators, like Swift does. I think that would work as well, or even better, but we've been avoiding having any operators which aren't familiar from C.<br>

</blockquote>
<br></div>
The general flavor of this proposal w/r/t checked arithmetic sounds pretty reasonable to me, and we can probably make progress on this now. I particularly think that having checked types that use operator overloading is important for ergonomics.<br>

______________________________<u></u>_________________<br>
Rust-dev mailing list<br>
<a href="mailto:Rust-dev@mozilla.org" target="_blank">Rust-dev@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/rust-dev" target="_blank">https://mail.mozilla.org/<u></u>listinfo/rust-dev</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>   Jerry
</div>