Shorthand for Int32 literals in Julia

330 Views Asked by At

I use lots of Int32s in my code because I have some large arrays of those. But for some x::Int32 we have typeof(x+1) == Int64 since numeric literals are Int64 by default (I have to use 64bit Julia to handle my arrays). The problem is, if I have some function f(x::Int32) then f(x+1) will method error. I don't want to implement a f(x::Int64) = f(convert(Int32, x)) for almost every function and want to use concrete types for type stability. Currently, I simply have expressions like x + Int32(1) all over my code which looks really cluttered. For other types we have shorthands, i.e., 1.f0 gives me a Float32 and big"1" a BigInt. Is there something similar for Int32?

3

There are 3 best solutions below

0
ahnlabb On BEST ANSWER

Since you explicitly mention the big_str macro (big"") you can easily define a similar macro for Int32 (the same way the uint128_str and int128_str is defined):

macro i32_str(s)
    parse(Int32, s)
end
julia> typeof(i32"1")
Int32

this might still clutter your code too much so alternatively you could exploit that a number followed by a name is multiplication:

struct i32 end

(*)(n, ::Type{i32}) = Int32(n)
julia> typeof(1i32)
Int32
2
Shayan On

What if you say:

# Or, a::Int32 = 1
julia> a = Int32(1)
1

julia> b::Int32 = a+2
3

julia> typeof(b)
Int32

julia> f(b)
...
0
mcabbott On

You can make a macro to replace every literal integer with an Int32, a bit like what ChangePrecision.jl does for floats. A very quick first attempt is:

julia> macro literal32(ex)
         esc(literal32(ex))
       end;

julia> literal32(ex::Expr) = Expr(ex.head, literal32.(ex.args)...);

julia> literal32(i::Int) = Int32(i);

julia> literal32(z) = z;  # ignore Symbol, literal floats, etc.

julia> @literal32 [1,2] .+ 3
2-element Vector{Int32}:
 4
 5

julia> @literal32 function fun(x::AbstractVector)
         x[1] + 2  # both 1 and 2 are changed
       end
fun (generic function with 1 method)

julia> fun(Int32[3,4]) |> typeof
Int32

One place this may have unexpected consequences is literal type parameters:

julia> @literal32([1,2,3]) isa Array{Int32,1}
true

julia> @literal32 [1,2,3] isa Array{Int32,1}
false

Another is that x^2 will not use Base.literal_pow, e.g. @literal32 Meta.@lower pi^2.