When I get a string s=“x^2+1” (It can only be a string), then how do I create a function f(x)=x^2+1. I tried the following with metaprogramming, but it didn’t work
julia> s="x^2+1"
"x^2+1"
julia> f(x)=eval(Meta.parse(s))
f (generic function with 1 method)
julia> f(1)
ERROR: UndefVarError: x not defined
Stacktrace:
[1] top-level scope
@ none:1
[2] eval
@ ./boot.jl:373 [inlined]
[3] eval
@ ./client.jl:453 [inlined]
[4] f(x::Int64)
@ Main ./REPL[2]:1
[5] top-level scope
@ REPL[3]:1
It seems that eval() can only work on expressions that contain global variables that have been defined.
Of course. What you do is the same as entering at the REPL:
x^2+1
which gives you the same error if x is not defined.
The argument eval is evaluated independently from what you put in front of it, (f(x) in this case).
What you actually do, is defining a function which ignores its argument x. The body of the function does the eval in the Main scope, and not in the scope of the function, so it’s a different x as the functions argument.
help?> eval
...
eval(expr)
Evaluate an expression in the global scope ...
Apart from “please try to avoid doing this in the first place” this is hard to answer properly without knowing how it’s going to be used and how the example is supposed to generalize.
Here is another approach that may or may not be useful:
julia> function foo(s, x)
f = eval(Meta.parse("x -> $s"))
return Base.invokelatest(f, x)
end
foo (generic function with 1 method)
julia> foo("2x+1", 3)
7