Metaprogramming: create function which takes arguments (vector and expression) to evaluate

question
#1

I have an expression e = :(x[3] ^ 2.0) that I hope to turn into a function which will evaluate e at x given arguments e and x. I tried the below but am messing something up.

function f(ex::Array{Float64,1}, expr::Expr)
    [x[i] = eval(ex[i]) for i =1:length(ex)]
    return eval(expr)
end

It differs slightly from this question because my input is an array which I’m not sure how to loop over (I also tried the following)

function g(x)
    return :(x[3] ^ 2.0)
end
@eval function f(x)
    $(g(x))
end
0 Likes

#2

Well, the first part of Kristoffer’s answer to the thread you linked is certainly relevant: it’s always worth asking whether you need metaprogramming at all. Why do you have an AST in this case rather than a function which you can use directly?

Anyway, to answer the question quite literally: If you must take an AST from somewhere and make a function from it:

function make_func(ex)
    # <-- Insert some validation that `ex` has the required form here.
    # Especially if `ex` is untrusted, you should whitelist allowed forms.
    g = gensym("myfunc")
    @eval function $g(x)
        $ex
    end
end

ex = :(x[3] ^ 2.0)
g = make_func(ex)

g([1,2,3])
3 Likes