# Evaluate Created Expression Within Function

**URL:** https://discourse.julialang.org/t/evaluate-created-expression-within-function/73879
**Category:** New to Julia
**Created:** [December 31, 2021, 9:20pm UTC](https://discourse.julialang.org/t/evaluate-created-expression-within-function/73879 "2021-12-31T21:20:52Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![HiramTheHero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hiramthehero/32/218391_2.png) [@HiramTheHero](https://discourse.julialang.org/u/HiramTheHero)
#### Post date: [December 31, 2021, 9:20pm UTC](https://discourse.julialang.org/t/evaluate-created-expression-within-function/73879/1 "2021-12-31T21:20:52Z")

</div>

Hello all.

I am writing some code that adds syntax sugar to subsetting dataframes.

I want to pass `:(:SepalLength .> (:SepalWidth .* 2))` and `df` into a function and it create a BitVector by evaluating `df.SepalLength .> (df.SepalWidth .* 2)`.

I created a function that turns

`:(:SepalLength .> (:SepalWidth .* 2))`

into

`:(df.SepalLength .> (df.SepalWidth .* 2))`.

However, when I try evaluating the new expression with `eval()` I run into an error because it evaluates it at the global scope and `df` is not defined.

At this time the only way I know how to overcome this issue is by evaluating an expression within a local scope. Is this possible? If not, is there another way to approach this problem to get similar results?

Here is the function. I’m sure there are many issues with it, but the part I am mainly concerned about is evaluating the newly created expression to return a BitVector. Other feedback is welcomed too. Thank you all for your time and aid.

NOTE: I know DataFramesMeta exists. This is for something different.

```julia
function subsettingExpressionToBitVector(df::DataFrame, ex::Expr)
    newCollec = []
    for expression in ex.args
    if typeof(expression) <: Expr
        expression = subsettingExpressionToBitVector(df, expression)
    end

if typeof(expression) <: QuoteNode
    if eval(expression) ∈ propertynames(df)
    column = propertynames(df)[eval(expression) .== propertynames(df)][1]
    expression = Expr(:., Symbol("df"), QuoteNode(column))
    end
end
    push!(newCollec, expression)
end
newExpr = Expr(:call, newCollec...)

    return eval(newExpr) # Using eval() is the issue.
end

```

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [January 1, 2022, 2:57am UTC](https://discourse.julialang.org/t/evaluate-created-expression-within-function/73879/2 "2022-01-01T02:57:18Z")

</div>

`eval` only works in `global` scope, however, what you want do not seem to be a function but instead a `macro`, which is _basically_ a function that takes whatever arguments as an expression, at compile time, and return an expression to substitute itself before the code is compiled. Did you look at `macro`s in Julia Manual?

---

<div class="post-metadata">

### Author: ![HiramTheHero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hiramthehero/32/218391_2.png) [@HiramTheHero](https://discourse.julialang.org/u/HiramTheHero)
#### Post date: [January 1, 2022, 3:33pm UTC](https://discourse.julialang.org/t/evaluate-created-expression-within-function/73879/3 "2022-01-01T15:33:59Z")

</div>

Thank you for the reply. Yes, I have looked at macros a couple of times in the manual. I must admit I was avoiding them because I don’t understand them well. (I will look into them now.) Is there no way to execute an eval() command on the local scope? (Or something similar.) I haven’t been able to find anything about it.

Thank you again for your help.

---

<div class="post-metadata">

### Author: ![melonedo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/melonedo/32/15503_2.png) [@melonedo](https://discourse.julialang.org/u/melonedo)
#### Post date: [January 2, 2022, 3:07am UTC](https://discourse.julialang.org/t/evaluate-created-expression-within-function/73879/4 "2022-01-02T03:07:48Z")

</div>

No, it is by design that `eval` is limited to global scope, so that everything in the local scope is monitored by the JIT compiler, which is a prerequisite for optimizations.

As for your question, a macro is exactly what you need:

```julia
replace_symbol(ex, obj) = ex
replace_symbol(sym::QuoteNode, obj) = :($obj.$(sym.value))
replace_symbol(ex::Expr, obj) = Expr(ex.head, replace_symbol.(ex.args, obj)...)
macro replace_sym(sym, ex)
	# escape the whole expression so that they represent variables in the caller's scope instead of local to the macro
	esc(replace_symbol(ex, sym))
end
let
	df = DataFrame(a=1:4, b=3:6)
	@replace_sym df :a .> :b .* 2
end

```
