How to create a function from a vector of expressions?

From
How do I create a function from an expression - General Usage - JuliaLang

function genfun(expr, args::Tuple, gs=gensym())
    eval(Expr(:function,Expr(:call, gs, args...),expr))
    (args...) -> Base.invokelatest(eval(gs), args...)
end

e3 = :(a + b + c)
add3 = genfun(e3, (:a,:b,:c))
add3(1,2,3) # -> 6

I would like to extend to a vector of expressions, evaluating one expression after the other, like (without function generation):

evec = [:(a = 1 + 2), :(b = 2*a)]
foreach(eval, evec)
b # -> 6

How to create a corresponding function like above?

If you wanted to compose all of the expressions into one super-expression, :block is the construct. dump is a useful tool for learning these sorts of things.

julia> quote; a = 1 + 2; b = 2*a; end |> dump
...
# dump shows that a multiline Expr has :block as the top-level construct

julia> Expr(:block,evec...)
quote
    a = 1 + 2
    b = 2a
end
# the quote here matches the above - or you can dump to see in more-precise detail

So this assembles the Vector{Expr} into a single Expr object. It appears your genfun can take you from there.

2 Likes

dump again (pun intended)
Thanks a lot!

evec = [:(a[3] = a[1] + a[2]), :(a[4] = a[2] + a[3])]
eblk = Expr(:block,evec...)
fib = genfun(eblk, (:a,))
a = [1,1,0,0]
fib(a)
a

4-element Vector{Int64}:
 1
 1
 2
 3

Continued in
https://discourse.julialang.org/t/executing-a-vector-of-expressions-some-benchmarks/