Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any way to 'expand' a generated function in Julia?

Tags:

julia

Is there a way to get the expression that a Julia generated function creates without evaluating it, something like @macroexpand but for generated functions?

For example, say we have

@generated function blah(x)
    if x <:Integer
        :(x)
    else
        :(x * 2)
    end
end

Then:

julia> blah(1), blah(2.)
(1, 4.0)

What I want is a macro that works something like:

julia> @generatedexpand blah(2.)
:(x * 2)
like image 207
mrip Avatar asked Feb 27 '21 18:02

mrip


2 Answers

You could try @code_lowered:

julia> @code_lowered blah(4)
CodeInfo(
    @ REPL[1]:1 within `blah'
   ┌ @ REPL[1]:1 within `macro expansion'
1 ─│     return x
   └
)

julia> @code_lowered blah(4.5)
CodeInfo(
    @ REPL[1]:1 within `blah'
   ┌ @ REPL[1]:1 within `macro expansion'
1 ─│ %1 = x * 2
└──│      return %1
   └
)

Or you can use code_lowered function:

julia> code_lowered(blah,(Int,))[1].code
1-element Vector{Any}:
 :(return _2)

julia> code_lowered(blah,(Float64,))[1].code
2-element Vector{Any}:
 :(_2 * 2)
 :(return %1)
like image 102
Przemyslaw Szufel Avatar answered Oct 13 '22 10:10

Przemyslaw Szufel


One way you can do this is to make the "body" of the generated function a standalone function. Here's a demo:

julia> function blah_generator(x)
           if x <:Integer
               :(x)
           else
               :(x * 2)
           end
       end
blah_generator (generic function with 1 method)

julia> @generated function blah(x)
           blah_generator(x)
       end
blah (generic function with 1 method)

julia> blah(2)
2

julia> blah(2.0)
4.0

julia> blah_generator(typeof(2))
:x

julia> blah_generator(typeof(2.0))
:(x * 2)
like image 1
tholy Avatar answered Oct 13 '22 09:10

tholy