Passing a function to an eval in my module

I made a module which had a function, that calls another function inside of it to compute partial derivatives. I tested it with Base functions like exp, sin and so on and it worked, it still works. I also tested it with my own functions inside the notebook before copying all the code into a module.

Now when I import my module the function only works with Base functions, when I pass my own I get the error “UndefVarError: myfunc not defined”

I threw in the debug print in there, and the correct value for myfunc(1, 2, 3) gets printed, so the function is visible in the scope of the module once it’s been passed to the function, right? But when calling eval, it’s no longer visible. I need to use eval since I want it to work with functions that have any amount of arguments, unless there are better ways to do it, I’m open to any suggestions and knowledge about how scopes work with eval and expressions.

I read this https://docs.julialang.org/en/v1/manual/variables-and-scoping/ for any hints, but didn’t seem to find my answer, maybe I missed it.

function _partial_derivative(args::AbstractArray, idx::Integer, f::Function)
        print(f(1, 2, 3)) #still prints in Main
        args = (arg -> [[arg 0]; [0 arg]]).(args)
        args[idx] += [[0 1]; [0 0]]
        expr = ""
        for arg in args
            expr = "$expr, $arg" #make a string of my arguments
        end
        expr = expr[3:end]
        f_expr = Meta.parse("$f($expr)") #combine the function and the arguments, evaluate
        res = eval(f_expr)
        return res[1, 1], res[1, 2] #return the function and its partial derivative
end

You can eval into a particular module. But you almost definitely don’t want to be doing this. Rather, you want to define closures.

1 Like

I think you’re looking for the splat operator ... – in this case f(args...).

2 Likes

It works, never knew it can be used not just in function definitions. Thank you!

Also note that you pretty much never want to manipulate Julia code as strings. Manipulating code as Expr objects is much less of a hassle and a lot less error prone. Have a look at the metaprogramming section in the manual:
https://docs.julialang.org/en/v1/manual/metaprogramming/.

2 Likes