# Using eval within a function

**URL:** <https://discourse.julialang.org/t/using-eval-within-a-function/82487>\
**Category:** General Usage\
**Tags:** metaprogramming, syntax, eval, parser\
**Created:** [June 9, 2022, 11:04am UTC](https://discourse.julialang.org/t/using-eval-within-a-function/82487 "2022-06-09T11:04:08Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![flobe](https://avatars.discourse-cdn.com/v4/letter/f/977dab/32.png) [@flobe](https://discourse.julialang.org/u/flobe)\
**Post date:** [June 9, 2022, 11:04am UTC](https://discourse.julialang.org/t/using-eval-within-a-function/82487/1 "2022-06-09T11:04:08Z")

</div>

I’m trying to build a statement for an if case within a function. Something like:

```julia
function build_string(test_value, comparator, value)
    if eval(Meta.parse("test_value" * "comparator" * "value"))
    [...]
end

```

… I get the error, that the parameters within the function are not known. As I already read, in the other topic, `eval` is only working globally and it should be avoided to use it within a function. However I’d like to get this to work. The only other option would be to make if cases which compares every possible value of the comparator parameter … but this would make the function huge.

I hope you understand what I am struggling with. 🤔

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [June 9, 2022, 11:11am UTC](https://discourse.julialang.org/t/using-eval-within-a-function/82487/2 "2022-06-09T11:11:57Z")

</div>

I’m 99% sure `eval` is not the answer. Some alternatives:

- Pass `comparator` as a function, then just call it.
- If it must be a string, have a bunch of `if comparator == "foo" ...` branches.
- Or have a global const dict mapping comparators to the function implementing it (e.g. `Dict("==" => ==, ...)`). This will be type-unstable.

---

<div class="post-metadata">

**Author:** ![skleinbo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skleinbo/32/36080_2.png) [@skleinbo](https://discourse.julialang.org/u/skleinbo)\
**Post date:** [June 9, 2022, 11:22am UTC](https://discourse.julialang.org/t/using-eval-within-a-function/82487/3 "2022-06-09T11:22:29Z")

</div>

`eval` evaluates the expression _in the global scope of the containing module_ (cf. the documentation). You cannot use it in a function body like that. But you have noticed that yourself 🙂

If `comp` is a function, then simply do what @Sukera wrote below. If it is unavoidably a string (for whatever reason), a macro would make this work

```julia
macro comp_string(test, comp, val)
  c = Meta.parse(comp)
  :( $c($a, $b) )
end

@comp_string("A", "<=", "B")
true

function build_string(A, comp, B)
  if @comp_string(A, comp, B)
   [...]
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:** [June 9, 2022, 11:47am UTC](https://discourse.julialang.org/t/using-eval-within-a-function/82487/4 "2022-06-09T11:47:19Z")

</div>

You can avoid macros by passing in the function directly:

```julia
function build_string(A, comp, B)
  if comp(A, B)
   [...]
end

build_string(A, <=, B) # for some variables A and B

```

---

<div class="post-metadata">

**Author:** ![skleinbo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skleinbo/32/36080_2.png) [@skleinbo](https://discourse.julialang.org/u/skleinbo)\
**Post date:** [June 9, 2022, 11:48am UTC](https://discourse.julialang.org/t/using-eval-within-a-function/82487/5 "2022-06-09T11:48:59Z")

</div>

Sure, but I had understood OP that the requirement was to pass `comp` as a string. For whatever reason.

---

<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:** [June 9, 2022, 11:50am UTC](https://discourse.julialang.org/t/using-eval-within-a-function/82487/6 "2022-06-09T11:50:58Z")

</div>

I don’t think so - else there would be no need to `Meta.parse` a custom built string again (in the example they’re parsing `test_value <= value`, just without interpolating the comparator properly/having the proper syntax), only to evaluate the resulting expression.

---

<div class="post-metadata">

**Author:** ![skleinbo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skleinbo/32/36080_2.png) [@skleinbo](https://discourse.julialang.org/u/skleinbo)\
**Post date:** [June 9, 2022, 11:55am UTC](https://discourse.julialang.org/t/using-eval-within-a-function/82487/7 "2022-06-09T11:55:50Z")

</div>

Huh, you’re right. Then I don’t understand OP’s objective at all.

---

<div class="post-metadata">

**Author:** ![flobe](https://avatars.discourse-cdn.com/v4/letter/f/977dab/32.png) [@flobe](https://discourse.julialang.org/u/flobe)\
**Post date:** [June 9, 2022, 2:31pm UTC](https://discourse.julialang.org/t/using-eval-within-a-function/82487/8 "2022-06-09T14:31:52Z")

</div>

Thanks very much! I had not expected to be able to pass the `comp` directly as function … very happy with the outcome =)
