Typed globals: macro to define multiple, without manual type annotations

Not sure if something like this is already in a package somewhere, but here’s one way to write such a macro:

function rewrite_assignment(@nospecialize(ex))
    if Meta.isexpr(ex, :(=))
        l, r = ex.args
        l isa Symbol || error("Destructuring not supported")
        tmp = gensym(l)
        return esc(:(let $tmp = $r; global $l::typeof($tmp) = $tmp end))
    elseif Meta.isexpr(ex, :block)
        return Expr(:block, Base.mapany(rewrite_assignment, ex.args)...)
    else
        return ex
    end
end

macro typed(ex)
    return rewrite_assignment(ex)
end
julia> @typed begin
         a = 2
         b = 2.8
       end
2.8

julia> code_typed() do
           a, b
       end
1-element Vector{Any}:
 CodeInfo(
1 ─ %1 = Main.a::Int64
│   %2 = Main.b::Float64
│   %3 = Core.tuple(%1, %2)::Tuple{Int64, Float64}
└──      return %3
) => Tuple{Int64, Float64}
5 Likes