JuliaLang/julia — comment on commit beef15d94496506c8148a76cd5970107ad69ad93
File:  line 0
By StefanKarpinski:

Perhaps what we need is that Uint32 + Uint32 => Uint32 on 32-bit systems. That would amount to adding a series of definitions like this:

```diff
diff --git a/j/int.j b/j/int.j
index af7f427..2cfe6d3 100644
--- a/j/int.j
+++ b/j/int.j
@@ -186,18 +186,22 @@ promote_rule(::Type{Uint64}, ::Type{Int64}) = Uint64
*{T<:Integer}(x::T, y::T) = int(x) * int(y)

-(x::Int) = boxsint(neg_int(unboxwd(x)))
+-(x::Uint) = boxuint(neg_int(unboxwd(x)))
-(x::Int64) = boxsi64(neg_int(unbox64(x)))
-(x::Uint64) = boxui64(neg_int(unbox64(x)))

+(x::Int, y::Int) = boxsint(add_int(unboxwd(x), unboxwd(y)))
++(x::Uint, y::Uint) = boxuint(add_int(unboxwd(x), unboxwd(y)))
+(x::Int64, y::Int64) = boxsi64(add_int(unbox64(x), unbox64(y)))
+(x::Uint64, y::Uint64) = boxui64(add_int(unbox64(x), unbox64(y)))

-(x::Int, y::Int) = boxsint(sub_int(unboxwd(x), unboxwd(y)))
+-(x::Uint, y::Uint) = boxuint(sub_int(unboxwd(x), unboxwd(y)))
-(x::Int64, y::Int64) = boxsi64(sub_int(unbox64(x), unbox64(y)))
-(x::Uint64, y::Uint64) = boxui64(sub_int(unbox64(x), unbox64(y)))

*(x::Int, y::Int) = boxsint(mul_int(unboxwd(x), unboxwd(y)))
+*(x::Uint, y::Uint) = boxuint(mul_int(unboxwd(x), unboxwd(y)))
*(x::Int64, y::Int64) = boxsi64(mul_int(unbox64(x), unbox64(y)))
*(x::Uint64, y::Uint64) = boxui64(mul_int(unbox64(x), unbox64(y)))

@@ -208,10 +212,12 @@ rem{T<:Integer}(x::T, y::T) = rem(int(x),int(y))
mod{T<:Integer}(x::T, y::T) = mod(int(x),int(y))

div(x::Int, y::Int) = boxsint(sdiv_int(unboxwd(x), unboxwd(y)))
+div(x::Uint, y::Uint) = boxuint(sdiv_int(unboxwd(x), unboxwd(y)))
div(x::Int64, y::Int64) = boxsi64(sdiv_int(unbox64(x), unbox64(y)))
div(x::Uint64, y::Uint64) = boxui64(udiv_int(unbox64(x), unbox64(y)))

rem(x::Int, y::Int) = boxsint(srem_int(unboxwd(x), unboxwd(y)))
+rem(x::Uint, y::Uint) = boxuint(srem_int(unboxwd(x), unboxwd(y)))
rem(x::Int64, y::Int64) = boxsi64(srem_int(unbox64(x), unbox64(y)))
rem(x::Uint64, y::Uint64) = boxui64(urem_int(unbox64(x), unbox64(y)))
```

That way both signed and unsigned arithmetic in the native type are always type-stable. On 32-bit, you would only resort to 64-bit when mixing signed and unsigned 32-bit operands. Another approach would be to make 32-bit types on 32-bit systems more of a ceiling and only switch to 64-bit when an actual 64-bit value was introduced. That would actually make 64-bit and 32-bit systems more analogous; if you imagine a 128-bit integer type on 64-bit systems, this might be the kind of behavior one would want — "don't resort to 128-bit arithmetic unless I explicitly ask you to by using a 128-bit value."