I have been messing around with generated functions in Julia, and have come to a weird problem I do not understand fully: My final goal would involve calling a macro (more specifically @tullio
) from within a generated function (to perform some tensor contractions that depend on the input tensors). But I have been having problems, which I narrowed down to calling the macro from within the generated function.
To illustrate the problem, let’s consider a very simple example that also fails:
macro my_add(a,b)
return :($a + $b)
end
function add_one_expr(x::T) where T
y = one(T)
return :( @my_add($x,$y) )
end
@generated function add_one_gen(x::T) where T
y = one(T)
return :( @my_add($x,$y) )
end
With these declarations, I find that eval(add_one_expr(2.0))
works just as expected and returns and expression
:(@my_add 2.0 1.0)
which correctly evaluates to 3.0
.
However evaluating add_one_gen(2.0)
returns the following error:
MethodError: no method matching +(::Type{Float64}, ::Float64)
Doing some research, I have found that @generated
actually produces two codes, and in one only the types of the variables can be used. I think this is what is happening here, but I do not understand what is happening at all. It must be some weird interaction between macros and generated functions.
Can someone explain and/or propose a solution? Thank you!