I have a macro to generate code for “many” binary operations. The macro generates several functions, including a @generated function so that I can generate code for any combination of subtypes. A crash reproduction of my code looks like this
macro Op2(OP,A,B)
return quote
@generated function $OP(a::MyType{Ta},b::MyType{Tb}) where{Ta,Tb}
return quote
MyType{Ta}($OP(a.x*$A,b.x*$B))
end
end
end
end
struct MyType{T}
x::Float64
end
and it makes a big fireball
@Op2(Base.:(+),1.,2.)
x = MyType{1}(3.)
y = MyType{2}(2.)
x+y
ERROR: LoadError: UndefVarError: A not defined
I am surprised: I would expect the macro’s outermost interpolated quote to replace OP, A and B, return code to the effect of
@generated function Base.:(+)(a::MyType{Ta},b::MyType{Tb}) where{Ta,Tb}
return quote
MyType{Ta}(Base.:(+)(a.x*1.,b.x*2.))
end
end
but this is not what seems to happen: I can’t say I can cut through the fog returned by @macroexpand, but it still mentions OP, A and B. What did I miss?
Code that generates code is bad for the brain, but code that generates code that generates code? Is it really wise?