I’m working on a piece of code that generates a math expression with embedded variables, and I want to generate a function that will take those variables as inputs and evaluate the math expression using the given inputs. E.g., if my math expression ends up being
a + b, I want to have a generated function that takes
b as inputs and will evaluate
a + b. The purpose of this is that generating my math expression takes a lot of time, but once I have the math expression, evaluating it should be fast, and I want to be able to evaluate it with different variables a large number of times.
My thinking was to use a nested function approach where the variable names and final math expression are interpolated into an inner function definition, which hopefully I can later call to evaluate the equation. Here’s a contrived example of what I’m trying to do where the math expression is just a sum of
function make_func(num::Int) # Generate some variables vars = String for i = 1:num push!(vars, "v"*string(i)) end # Generate an equation using these variables my_sum = "" for var in vars my_sum = my_sum * var * " + " end my_sum = my_sum[1:end-3] # Create a function that will evaluate this equation @eval begin function new_func(vars...) the_sum = Meta.parse($my_sum) return the_sum end end end
make_func(3) would generate a function called
new_func which takes 3 inputs, calculates the sum of the values, and returns the sum. But this doesn’t work:
julia> make_func(3); new_func(1,5,7) :(v1 + v2 + v3) julia> new_func() :(v1 + v2 + v3)
For one thing,
new_func(vars...) is clearly not creating a function where the elements of “vars” are the arguments. And for another thing, the
:(v1 + v2 + v3) expression seems to be detached from the inputs to
new_func, which means I can’t get its evaluation.
Is there any way to do something like this? Some fix to the nested function? A way to evaluate a code-generated expression multiple times without re-generating it?
Any help would be greatly appreciated!