# How to avoid evaluation into the global space when the expression is not know in advance

**URL:** https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342
**Category:** General Usage
**Tags:** strings, eval
**Created:** [August 30, 2021, 11:41am UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342 "2021-08-30T11:41:10Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![JianghuiDu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jianghuidu/32/8028_2.png) [@JianghuiDu](https://discourse.julialang.org/u/JianghuiDu)
#### Post date: [August 30, 2021, 11:41am UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/1 "2021-08-30T11:41:10Z")

</div>

```julia
input = Dict("x"=>ones(10),"y"=>2*ones(10),"z"=>3*ones(10))

expr_list = DataFrame(var=["v1","v2","v3"],expr = ["x*y","y/z","x+y+z"])

output = Dict()

```

I have a dictionary of `input` storing the values of some variables `x,y,z`. Output variables `v1,v2,v3` are calculated based on their definition in the `expr_list`.

I’ve heard that `eval` should be avoided in such calculations, but the examples I found assume that you already know the expressions so you can do something to avoid `eval`. But if the `expr_list` is not know in advance what should I do?

Here is my bad solution using `eval`. This enters `x,y,z` into the global space, which I don’t want.

```julia

for (key,value) in input

    eval(Meta.parse("$key = $value"))

end

for i in eachrow(expr_list)

    output[i.var] = eval(Meta.parse("@. $(i.expr)"))

end

```

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [August 30, 2021, 11:58am UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/2 "2021-08-30T11:58:03Z")

</div>

You cannot avoid evaluating into global scope if you want to parse strings and evaluate them. Julias semantics “only” allow for functions to see the result of `eval` when they return back to global scope. It’s a key aspect of the language, which allows it to be compiled & fast while still being a dynamic language. You can find an analysis of why that is [here](https://arxiv.org/pdf/2010.07516.pdf) (it’s a little longer, but well worth the read).

What are you trying to evaluate/interpret in the first place? How did you arrive at a solution involving `eval`? Maybe there’s a better abstraction for what you’re originally trying to do, we could help you find that abstraction if you tell us a little more about it.

---

<div class="post-metadata">

### Author: ![JianghuiDu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jianghuidu/32/8028_2.png) [@JianghuiDu](https://discourse.julialang.org/u/JianghuiDu)
#### Post date: [August 30, 2021, 12:04pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/3 "2021-08-30T12:04:40Z")

</div>

The `input` are results from previous calculations generated by the modeler. The `expr_list` is supplied by the user using “txt” or “xlsx” files, which the modeler doesn’t know in advance. The modeler should calculate the new variables based on the `expr_list` and generate an output “txt” or “xlsx” file.

I don’t want `x,y,z` to enter the global space in this calculation because they might already have values in the global space. Or that these names might be used again later.

---

<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: [August 30, 2021, 12:20pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/4 "2021-08-30T12:20:01Z")

</div>

> [@JianghuiDu](#):
>
> I’ve heard that `eval` should be avoided in such calculations, but the examples I found assume that you already know the expressions so you can do something to avoid `eval` . But if the `expr_list` is not know in advance what should I do?

Don’t store expressions as strings. Store them as functions.

```julia
function_list = [(x,y,z) -> x*y, (x,y,z) -> y/z, (x,y,z) -> x+y+z]
input = (ones(10), 2*ones(10), 3*ones(10))
output = [f.(input...) for f in function_list]

```

---

<div class="post-metadata">

### Author: ![JianghuiDu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jianghuidu/32/8028_2.png) [@JianghuiDu](https://discourse.julialang.org/u/JianghuiDu)
#### Post date: [August 30, 2021, 12:28pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/5 "2021-08-30T12:28:43Z")

</div>

The problems are that

1. The `expr_list` is supplied by as string expressions in a “txt/xlsx” file. Can you convert a string to a function without `eval`.
2. In reality there are hundreds of variables in the input list `x,y,z,a,b,c,d,.....`, I’m only showing three here as an examples. To write anonymous functions like `(x,y,z,a,b,c,d...) - > ...` is unwieldy.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [August 30, 2021, 12:51pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/6 "2021-08-30T12:51:54Z")

</div>

> [@JianghuiDu](#):
>
> Can you convert a string to a function without `eval` .

No.

* * *

It really sounds like you’d want whoever is using your code to write julia code - why not let them do that in the first place? Instead of you trying to parse & run their code, you could structure your code as a library for them to use & include in _their_ code.

---

<div class="post-metadata">

### Author: ![JianghuiDu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jianghuidu/32/8028_2.png) [@JianghuiDu](https://discourse.julialang.org/u/JianghuiDu)
#### Post date: [August 30, 2021, 1:01pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/7 "2021-08-30T13:01:01Z")

</div>

I’m not sure what you mean. I feel this should be a very simple task, just processing existing data into new output. So unless you _manually_ write the expressions and turn into functions etc like @stevengj did, there’s not way to avoid `eval` ?

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [August 30, 2021, 1:31pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/8 "2021-08-30T13:31:03Z")

</div>

You’re asking about taking julia code (are you?) in form of strings and running that as code. If that’s not what `eval` does, I don’t know what is.

Like I said, it kind of sounds like you’d want people to write julia code in the first place. That code could either use your code as a library or you `include` or `eval` it. If we’re not talking about julia code in form of strings, what are we talking about exactly?

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [August 30, 2021, 1:33pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/9 "2021-08-30T13:33:55Z")

</div>

I think the simplest solution to what you want is to make the user write the functions as:

```julia
(x,y) -> x*y
(x,y,z) -> x + y + z

```

```julia
julia> string1 = "(x,y) -> x*y"
"(x,y) -> x*y"

julia> f1 = eval(Meta.parse(string1))
#7 (generic function with 1 method)

julia> f1(2,2)
4

```

Then you can `eval` those expressions, which will define functions (in the global scope, but is always the case, AFAIK).

It become more complicated if you really don’t want the user to have understand that `(x,y)->x*y` is a function that receives `x` and `y` and returns `x*y`. You could write your own “list your variables here” table in the format you find convenient. If you wan’t to avoid the user to even listing which are the variables, than you have write some sort of parsers yourself for the strings, to get them.

That can work, and I see the potential uses of that, particularly for a simple user interface, some educational software, etc. For a more involved computation all that parsing of strings will become cumbersome and very error prone.

---

<div class="post-metadata">

### Author: ![JianghuiDu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jianghuidu/32/8028_2.png) [@JianghuiDu](https://discourse.julialang.org/u/JianghuiDu)
#### Post date: [August 30, 2021, 1:35pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/10 "2021-08-30T13:35:25Z")

</div>

That’s much more complex than what I’m looking for. Maybe my description was confusing.

My aim is very simple: Suppose my friend give me two txt files, one `input` containing a data matrix of old variables, and one `expr_list` containing string expression of calculating new variables. (I don’t see how these files are generated matters, whether by Julia or not, assuming they are formatted correctly). My question is how do I calculate the output without `eval`?

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [August 30, 2021, 1:39pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/11 "2021-08-30T13:39:03Z")

</div>

> [@JianghuiDu](#):
>
> txt file of `expr_list` , how do I calculate the output without `eval` ?

the only (practical) way to turn arbitrary string into Julia function is through `eval`. If you know the expressions are polynomial etcl., you can parse the coefficients without `eval`, but from your original questions it sounds like the content of `expr_list` can be anything.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [August 30, 2021, 1:41pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/12 "2021-08-30T13:41:46Z")

</div>

What they are saying is that you can do this:

file: “data.jl”

```julia
data = [ 
           1,
           2,
 ]

```

file: functions.jl

```julia
functions = [ 
           x -> 2*x,
           x -> 3*x
]

```

then do:

```julia
julia> include("./data.jl")

julia> include("./functions.jl")

julia> for (f,d) in zip(functions,data)
          println(f(d))
       end
2
6

```

That is not that different from what you want, and you don’t need any complicated evaluation. Just need to give the input as to julia arrays with the proper syntax in the original files.

---

<div class="post-metadata">

### Author: ![JianghuiDu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jianghuidu/32/8028_2.png) [@JianghuiDu](https://discourse.julialang.org/u/JianghuiDu)
#### Post date: [August 30, 2021, 1:42pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/13 "2021-08-30T13:42:22Z")

</div>

Yes. They can be any combinations of elementary functions.

---

<div class="post-metadata">

### Author: ![JianghuiDu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jianghuidu/32/8028_2.png) [@JianghuiDu](https://discourse.julialang.org/u/JianghuiDu)
#### Post date: [August 30, 2021, 1:44pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/14 "2021-08-30T13:44:32Z")

</div>

I see. But I can’t ask people to write `function.jl` for me, I only have a txt or excel file containing the string expressions.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [August 30, 2021, 1:44pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/15 "2021-08-30T13:44:41Z")

</div>

That literally sounds like they’re basically writing julia code already, except they don’t want to/can’t write proper functions and are instead limited to a subset of julia that only works on the top level…?

If you don’t want to clobber the global scope, there’s no way around some kind of `eval` into a temporary module.

Also, treating non-julia code like julia code will probably run into weird edge cases in the future.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [August 30, 2021, 1:48pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/16 "2021-08-30T13:48:10Z")

</div>

> [@JianghuiDu](#):
>
> I only have a txt or excel file containing the string expressions.

So: either they can write the functions as

```julia
(x,y) -> x*y

```

and then use `eval` on those (that is fine for that purpose). Or, if you really only can expect the user to write

```julia
x*y

```

You need to parse that string to understand which are the variables (are they very limited? is it just checking if `x`, `y` and `z` are present?), and turn that into a string as:

```julia
(x,y) -> x*y

```

But how general you want the input to be will define how complicated this parsing will be.

---

<div class="post-metadata">

### Author: ![JianghuiDu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jianghuidu/32/8028_2.png) [@JianghuiDu](https://discourse.julialang.org/u/JianghuiDu)
#### Post date: [August 30, 2021, 1:50pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/17 "2021-08-30T13:50:50Z")

</div>

The advantage of this is that you generate anonymous functions that do not conflict with anything else in the the global namespace?

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [August 30, 2021, 1:51pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/18 "2021-08-30T13:51:13Z")

</div>

Exactly, they are just functions.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [August 30, 2021, 1:55pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/19 "2021-08-30T13:55:45Z")

</div>

Be aware that those functions will still be kept around for the duration of the running julia process and that the `functions` array proposed here would also hang around. There’s also no caching between similar functions, since they’d all be new anonymous functions and thus julia will have to compile them again and again.

---

<div class="post-metadata">

### Author: ![JianghuiDu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jianghuidu/32/8028_2.png) [@JianghuiDu](https://discourse.julialang.org/u/JianghuiDu)
#### Post date: [August 30, 2021, 1:56pm UTC](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342/20 "2021-08-30T13:56:42Z")

</div>

That seems to be the most simple solution.

[Next page](https://discourse.julialang.org/t/how-to-avoid-evaluation-into-the-global-space-when-the-expression-is-not-know-in-advance/67342.md?page=2)
