I would like to call a macro in a Julia package (@defNLExpr
in JuMP) using an argument that is runtime dependent. The argument is an expression that depends on the runtime parameter n
. The only way that I can think of doing this is something like the following:
macro macro1(x)
y=length(x.args);
return esc(:(k=$y-1))
end
macro macro2(n)
x="0";
for i=1:n
x="$x+$i"
end
x=parse(x);
return :(@macro1($x))
end
n=rand(1:3)
println(n)
if (n==1)
@macro2(1)
elseif (n==2)
@macro2(2)
elseif (n==3)
@macro2(3)
else
error("expected n in 1:3")
end
println(k)
Here I have assumed that my runtime n
will always be in the range 1-3. I use macro2
to build-up all possible expressions for these different possible values of n
, and call the external macro (which I have replaced by the simplified macro1
here) for each of them. The calls to macro1
are in if
statements, so only the correct one (determined from the value of n
at runtime) will actually be executed.
Although this seems to work, is there a more efficient way of achieving this?
@generated
functions. You should check them out in the docs – spencerlyon2@generated
functions only have access to the type of their arguments, and so the valuen
would not be known. – user3708067@generated
works on types of arguments, but you can "trick" the system into working for you. If you create a type with no fields, but one type parametern
, you can then use@generated
to do it. I haven't thought about your application, so I can't say I recommend this approach, but here's an example that does this. Notice that I neededd
loops (d
is a function argument). So I shoved that runtime valued
in as the type parameter onDegree
and let@generated
work onDegree{d}
– spencerlyon2n
is still just a symbol. – user3708067