# How to replace code with string in julia

**URL:** <https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654>\
**Category:** General Usage\
**Tags:** question\
**Created:** [May 31, 2023, 7:51am UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654 "2023-05-31T07:51:27Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Daptine](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daptine/32/50372_2.png) [@Daptine](https://discourse.julialang.org/u/Daptine)\
**Post date:** [May 31, 2023, 7:51am UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654/1 "2023-05-31T07:51:28Z")

</div>

My goal:  
I want to write a function that can generate functions based on user input string without much performance hit. For example

```julia
str = "x^2 + x^3"
function gen_func_from_str(str::String)
    function f(x)
         # something to make 
         # y = x^2 + x^3
    end
end

```

and the call `gen_func_from_str(str)` should return a function actually do what the `str` says.  
I have tried to use macro to resolve this, only to found that macro operate on code it self. So if I define a macro say `@gen_func`, using `@gen_func(str)` won’t do it as the macro only sees the `str` as a Symbol `:str`.  
Anther option is to use `eval(Meta.parse(str))` which seems to put the result in global scope with performance hit.  
My second thought is that maybe I should manipulate the code directly? For example, define the function like

```julia
function gen_func_from_str(str)
    new_str = "f(x) = " * str
    # create a file name tmp.jl
    # echo $new_str > tmp.jl
   include(path_of_tmp.jl)
   return f(x)
end

```

but this implementation seems to be quite strange…

Now I feel I am not heading at the right direction at all, should there be some straight forward implementation to `gen_func_from_str`?

---

<div class="post-metadata">

**Author:** ![jmair](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmair/32/35117_2.png) [@jmair](https://discourse.julialang.org/u/jmair)\
**Post date:** [May 31, 2023, 8:07am UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654/2 "2023-05-31T08:07:47Z")

</div>

Maybe just return an anonymous function instead?

```julia
function gen_func_from_str(str)
    anon_fn_str = "x->$str"
    return eval(Meta.parse(anon_fn_str))
end

# example
f = gen_func_from_str("x^2+2x")
f(2) # returns 8

```

You probably won’t get something much more performant than this as you will always need to parse the string and evaluate it to get a function. This way saves having to name the function and pollute the namespace.

---

<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:** [May 31, 2023, 8:15am UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654/3 "2023-05-31T08:15:20Z")

</div>

Or check out:

> **[GitHub - SciML/RuntimeGeneratedFunctions.jl: Functions generated at runtime...](https://github.com/SciML/RuntimeGeneratedFunctions.jl)**
>
> Functions generated at runtime without world-age issues or overhead - GitHub - SciML/RuntimeGeneratedFunctions.jl: Functions generated at runtime without world-age issues or overhead

---

<div class="post-metadata">

**Author:** ![Daptine](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daptine/32/50372_2.png) [@Daptine](https://discourse.julialang.org/u/Daptine)\
**Post date:** [May 31, 2023, 9:05am UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654/4 "2023-05-31T09:05:06Z")

</div>

Thank you @jmair and @oheil !  
A little benchmarks shows that both solutions offers almost the same performance as anonymous functions, only that the second one avoids the use of `eval`. But the performance hit seems to be quite a lot compared to a standard Julia function. See the example:

```julia

using RuntimeGeneratedFunctions
RuntimeGeneratedFunctions.init(@ __MODULE__ )

function gen_func1(str)
    expression = Meta.parse("(x)->$str")
    f = @RuntimeGeneratedFunction(@ __MODULE__ , expression)
end

function gen_func2(str)
    anon_fn_str = "x->$str"
    return eval(Meta.parse(anon_fn_str))
end

func_baseline(x) = x^2 + 2x
func_anonymous = (x -> x^2 + 2x)
func_eval = gen_func1("x^2+2x")
func_rt_gen = gen_func2("x^2+2x")

using BenchmarkTools
@btime func_baseline(2) # 0.875 ns (0 allocations: 0 bytes)
@btime func_anonymous(2) # 14.097 ns (0 allocations: 0 bytes)
@btime func_eval(2) # 13.179 ns (0 allocations: 0 bytes)
@btime func_rt_gen(2) # 13.471 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

**Author:** ![Daptine](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daptine/32/50372_2.png) [@Daptine](https://discourse.julialang.org/u/Daptine)\
**Post date:** [May 31, 2023, 9:24am UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654/5 "2023-05-31T09:24:53Z")

</div>

And a tryout ugly implementation by directly manipulate the code file:

```julia
using Random
fn_name = randstring(5) # "Lyq1v"
str = "$fn_name(x) = x^2 + 2x"
open("/tmp/$fn_name.jl", "w") do io
    print(io, str)
end
include("/tmp/$fn_name.jl")
func = getfield(@ __MODULE__ , Meta.parse(fn_name))
@btime func(2) # 13.471 ns (0 allocations: 0 bytes)
# In case I know the name of the function
@btime Lyq1v(2) # 0.875 ns (0 allocations: 0 bytes)

```

Why such a big difference when just aliased `Lyq1v` to `func`?

---

<div class="post-metadata">

**Author:** ![Salmon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/salmon/32/22968_2.png) [@Salmon](https://discourse.julialang.org/u/Salmon)\
**Post date:** [May 31, 2023, 9:52am UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654/6 "2023-05-31T09:52:16Z")

</div>

> [@Daptine](#):
>
> But the performance hit seems to be quite a lot compared to a standard Julia function.

I think the problem is that `func_anonymous` by itself is just a global variable (pointing to the the anonymous function.  
If the reference to the anonymous function is in a local scope, (i think also when it is passed to another function) it is also fast and all are similar in performance.  
I think it is more reasonable to interpolate global references to anonymous functions in benchmarks, since that is likely reflecting better how they will be used later on:

```julia
@btime func_baseline(2) # 1.128 ns (0 allocations: 0 bytes)
@btime $func_anonymous(2) # 1.160 ns (0 allocations: 0 bytes)
@btime $func_rt_gen(2) # 1.127 ns (0 allocations: 0 bytes)

```

---

<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:** [May 31, 2023, 12:31pm UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654/7 "2023-05-31T12:31:42Z")

</div>

Non-const globals are bad for performance. Try

```julia
const func_anonymous = (x -> x^2 + 2x)
const func_eval = gen_func1("x^2+2x")
const func_rt_gen = gen_func2("x^2+2x")

```

---

<div class="post-metadata">

**Author:** ![Daptine](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daptine/32/50372_2.png) [@Daptine](https://discourse.julialang.org/u/Daptine)\
**Post date:** [June 1, 2023, 10:29am UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654/8 "2023-06-01T10:29:34Z")

</div>

Thank you for the tips! I am new to Julia, I didn’t know that global functions are also slow.

---

<div class="post-metadata">

**Author:** ![Salmon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/salmon/32/22968_2.png) [@Salmon](https://discourse.julialang.org/u/Salmon)\
**Post date:** [June 1, 2023, 3:53pm UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654/9 "2023-06-01T15:53:01Z")

</div>

Functions that you define in global scope are no problem,  
Here the issue is more than you create an anonymous function (which is fast by itself) but you afterwards create a global, non constant variable as an alias Name for the function. Since this variable could be of any type (you can make it a string in the line below), the compiler will not be able to figure out it’s type at compile time and the code is therefore slower.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 1, 2023, 3:53pm UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654/10 "2023-06-01T15:53:58Z")

</div>

> [@Daptine](#):
>
> I want to write a function that can generate functions based on user input string without much performance hit.

Why? Why not have the user pass a function instead? e.g. pass `(x,y) -> x^2 + y^2` instead of `"x^2 + y^2"`.

---

<div class="post-metadata">

**Author:** ![Daptine](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daptine/32/50372_2.png) [@Daptine](https://discourse.julialang.org/u/Daptine)\
**Post date:** [June 1, 2023, 4:54pm UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654/12 "2023-06-01T16:54:25Z")

</div>

I am trying to create an FEA applications that user can define custom boundary condition by inputing text in a Qt application. Currently the limitation is that users don’t have a julia REPL exposed, so the inputs are basically strings.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 1, 2023, 5:47pm UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654/13 "2023-06-01T17:47:14Z")

</div>

> [@Daptine](#):
>
> I am trying to create an FEA applications that user can define custom boundary condition by inputing text in a Qt application.

Yes, in that case `Meta.parse` and `eval` or similar (e.g. `include_string` to provide a REPL-like interface) are the main options. Should be fine in a real context where you only pay the dynamic-dispatch cost once (e.g. when you call your matrix-assembly function), not in your inner loops (as when you call with `@btime` using non-constant globals) – it’s easy for micro-benchmarks to be misleading here.

---

<div class="post-metadata">

**Author:** ![Daptine](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daptine/32/50372_2.png) [@Daptine](https://discourse.julialang.org/u/Daptine)\
**Post date:** [June 2, 2023, 3:54am UTC](https://discourse.julialang.org/t/how-to-replace-code-with-string-in-julia/99654/14 "2023-06-02T03:54:57Z")

</div>

Thank you for the tips!
