I am trying to provide a feature to allow a user to supply a function expression and have that expression evaluated at runtime.
The function needs two arguments, m and n. Both are assigned values before the evaluation.
function calculate(e::Expr)
m = rand(1:4, 5, 5)
n = rand(0:1, 5, 5)
return eval(e)
end
Why does the following not work?
d = :(rank(m * n))
julia> calculate(d)
ERROR: UndefVarError: m not defined
Stacktrace:
[1] top-level scope at none:0
[2] eval at ./boot.jl:330 [inlined]
[3] calculate(::Expr) at ./none:6
[4] top-level scope at none:0
The technical reason is that eval works in global scope. But as already been said, passing higher order functions is almost always the better API in cases like this.
Yes! Thank you. Using Function directly as the type did the trick.
calculate(reducef::Function = (m,n,f)->rank(m * n), ...) # this is the default function
…then… reducef(m, n, f)
@kristoffer.carlsson - I’m still not clear why eval() fails to work, even if I use eval(mymodule, expr). Are there built-in functions of Julia that can clarify the context in which code is evaluated at runtime? Very powerful stuff, this metaprogramming, but powerfully complicated as well.