First, thank you for taking the argument seriously.
I think that whether the change to the behavior of ā+ā should be considered fundamental is domain-dependent. I think that, for crypto, wrapping vs. overflowing + seems to be a fundamental distinction, and youād want a way to have both operations available at the same time with different names (design idea for that is below): crypto algorithms will usually have to consider the full field of available values, so that behavior on overflow (including whether overflow is allowed) is a core part of crypto design consideration. But for a 16-bit current-time-in-milliseconds, weād interpret a + b as āwhat will the time be b milliseconds after time a?ā There is, I think, little-to-no fundamental difference between that and, on Unix, time() + 10, even though time()-values on Unix should use checked semantics instead of wrapping. (There is, however, a semantic distinction between time_t (for the LHS) and time_diff_t (for the RHS).)
[example of making numerical operations semantics explicit. using this would, Iām sure, want the casting problem I mentioned earlier to have a better solution. but this idea makes it even more explicit that overflowing vs. wrapping is considered than a + b vs. a.wrapping_add(b) do.]
#[derive(Copy)]
struct CryptoNum<T: Int> CryptoNum(T);
trait CryptoAdd {
fn overflowing_add(self, rhs: Self) -> Self;
fn wrapping_add(self, rhs: Self) -> Self;
}
impl<T: Int> CryptoAdd for CryptoNum<T> { ... }