1

Can someone explain in simple terms why this error occurs and how it can be avoided except not placing the code in main in a function?

Please refer to question Improving the performance of SymPy function generated from string in Julia for the function string_to_func.

Works:

using SymPy

function string_to_func(function_string)
    func_lambdify = lambdify(SymPy.sympify(function_string), invoke_latest=false)
    @eval func(x, y, z) = ($func_lambdify)(x, y, z)
    return Nothing
end

function_string = "x + y + z"
string_to_func(function_string)
result = func(1, 2, 3)

Throws Error:

using SymPy

function string_to_func(function_string)
    expr = lambdify(SymPy.sympify(function_string), invoke_latest=false)
    @eval func(x, y, z) = ($expr)(x, y, z)
    return Nothing
end

function main()
    function_string = "x + y + z"
    string_to_func(function_string)
    result = func(1, 2, 3)
end

main()

Anonymized Error Message:

ERROR: LoadError: MethodError: no method matching func(::Int64, ::Int64, ::Int64)
The applicable method may be too new: running in world age 29676, while current world is 29678.
Closest candidates are:
  func(::Any, ::Any, ::Any) at path_to_folder\test.jl:5 (method too new to be called from this world context.)
Stacktrace:
 [1] main()
   @ Main path_to_folder\test.jl:12
 [2] top-level scope
   @ path_to_folder\test.jl:15
in expression starting at path_to_folder\test.jl:15
Felix
  • 83
  • 9

1 Answers1

2

You need to invoke func using Base.invokelatest, i.e.

function main()
    function_string = "x + y + z"
    string_to_func(function_string)
    result = Base.invokelatest(func, 1, 2, 3)
end

See the manual for further details about world age and why invokelatest is needed here.

I should also mention GeneratedFunctions.jl that can avoid some of the overhead associated with invokelatest, although it has it is own caveats since its somewhat of a hack.

Simeon Schaub
  • 735
  • 6
  • 11