# Converts the given string into code with metaprogramming

**URL:** <https://discourse.julialang.org/t/converts-the-given-string-into-code-with-metaprogramming/78819>\
**Category:** General Usage\
**Tags:** metaprogramming, strings\
**Created:** [March 31, 2022, 3:41pm UTC](https://discourse.julialang.org/t/converts-the-given-string-into-code-with-metaprogramming/78819 "2022-03-31T15:41:03Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![F-YF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/f-yf/32/17363_2.png) [@F-YF](https://discourse.julialang.org/u/F-YF)\
**Post date:** [March 31, 2022, 3:41pm UTC](https://discourse.julialang.org/t/converts-the-given-string-into-code-with-metaprogramming/78819/1 "2022-03-31T15:41:03Z")

</div>

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](https://docs.julialang.org/en/v1/manual/metaprogramming/), but it didn’t work

```julia
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.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [March 31, 2022, 3:44pm UTC](https://discourse.julialang.org/t/converts-the-given-string-into-code-with-metaprogramming/78819/2 "2022-03-31T15:44:12Z")

</div>

How about this:

```julia
julia> s="x^2+1"
"x^2+1"

julia> eval(Meta.parse("f(x)="*s))
f (generic function with 1 method)

julia> f(1)
2

```

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [March 31, 2022, 3:49pm UTC](https://discourse.julialang.org/t/converts-the-given-string-into-code-with-metaprogramming/78819/3 "2022-03-31T15:49:58Z")

</div>

> [@F-YF](#):
>
> 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:

```julia
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.

```julia
help?> eval
...
  eval(expr)

  Evaluate an expression in the global scope ...

```

---

<div class="post-metadata">

**Author:** ![F-YF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/f-yf/32/17363_2.png) [@F-YF](https://discourse.julialang.org/u/F-YF)\
**Post date:** [April 1, 2022, 1:36am UTC](https://discourse.julialang.org/t/converts-the-given-string-into-code-with-metaprogramming/78819/4 "2022-04-01T01:36:32Z")

</div>

> [@oheil](#):
>
> `eval(Meta.parse("f(x)="*s))`

Well, this works in the REPL.

> [@oheil](#):
>
> 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.

You’re right! This cannot be defined in the function body.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [April 1, 2022, 9:13am UTC](https://discourse.julialang.org/t/converts-the-given-string-into-code-with-metaprogramming/78819/5 "2022-04-01T09:13:13Z")

</div>

> [@oheil](#):
>
> `julia> eval(Meta.parse("f(x)="*s))`

Edited my typo… edited typo2 … and back… huuh, I am confused today…

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [April 1, 2022, 9:33am UTC](https://discourse.julialang.org/t/converts-the-given-string-into-code-with-metaprogramming/78819/6 "2022-04-01T09:33:35Z")

</div>

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
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

```

Cf. [Passing a string into function as a expression - #14 by GunnarFarneback](https://discourse.julialang.org/t/passing-a-string-into-function-as-a-expression/31625/14)

---

<div class="post-metadata">

**Author:** ![F-YF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/f-yf/32/17363_2.png) [@F-YF](https://discourse.julialang.org/u/F-YF)\
**Post date:** [April 2, 2022, 1:40am UTC](https://discourse.julialang.org/t/converts-the-given-string-into-code-with-metaprogramming/78819/7 "2022-04-02T01:40:55Z")

</div>

> [@GunnarFarneback](#):
>
> ```julia
> 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
> 
> ```

It was very helpful to me, thank you so much!
