How to calculate the typeof an expression without actually running it?


#1

Hi,

I would like to calculate the typeof an expression without running it. For example:

function f(x::Int)
    y = x+3
    if x > 0
        y+=1
    else
       y-=3
    end
    x+y
end

for example in a macro i am working with the expressions of this function and is there a way to calculate y+=1 to be type of Int?

Thanks


#2

You can get some information from inference but it’s in general impossible.


#3

And calling inference in your macro is almost certainly wrong.


#4

If you can elaborate a bit on what you’re trying to do, we may be able to provide some more useful advice. What is your macro doing that would require knowing the type of y inside the macro?


#5

Like yuyichao said this is probably not a good idea, but just for fun and education, there’s a macro (@code_typed) that shows you the inferred types. You can find what function it’s calling by doing:

macroexpand(:(@code_typed f(2)))

Turns out it’s calling code_typed in Base:

codeinfo = Base.code_typed(f,Tuple{Int64})[1]

You can get the inferred types from the CodeInfo object, e.g.:

function f(x) 
    z = 3
    y = 2.0x
end

codeinfo = Base.code_typed(f,Tuple{Int64})[1]
collect(zip(codeinfo.first.slotnames, codeinfo.first.slottypes))

4-element Array{Tuple{Any,Any},1}:
(Symbol("#self#"), #f)
(:x, Int64)
(:z, Int64)
(:y, Float64)

#6

Core.Inference.return_type. See it in action here: