# Metaprogramming & variable scope

**URL:** <https://discourse.julialang.org/t/metaprogramming-variable-scope/25819>\
**Category:** New to Julia\
**Tags:** metaprogramming\
**Created:** [June 28, 2019, 7:20pm UTC](https://discourse.julialang.org/t/metaprogramming-variable-scope/25819 "2019-06-28T19:20:08Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![versipellis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/versipellis/32/7878_2.png) [@versipellis](https://discourse.julialang.org/u/versipellis)\
**Post date:** [June 28, 2019, 7:20pm UTC](https://discourse.julialang.org/t/metaprogramming-variable-scope/25819/1 "2019-06-28T19:20:08Z")

</div>

I have some function as such:

```julia
function somefunction(df::AbstractDataFrame, indexcols::Array{Symbol,1})
...
    dummydf = similar(df,0)
    for col in indexcols
        dummydf[col] = []
        @eval $col = unique(df[$(QuoteNode(col))])
    end

...
    return dummydf
end

```

For the `@eval` statement in the `for` loop, it’s telling me that `df` is not defined. I’m guessing that it’s looking for `df` within the scope of the eval statement. I tried wrapping the `df` in QuoteNode, but that didn’t work either. What am I doing wrong here?

And as an extension to this… How does one get better at metaprogramming? I don’t come from a Clojure or LISP background, but I understand it and how it’s powerful from a conceptual perspective. Reading the docs has been… only somewhat useful, I think I’m at a much lower level than it’s expecting me to be.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [June 28, 2019, 7:48pm UTC](https://discourse.julialang.org/t/metaprogramming-variable-scope/25819/2 "2019-06-28T19:48:11Z")

</div>

This is less about metaprogramming in general and more about `@eval` (and `eval()`) in particular: `eval` always happens at _global scope_. This means that it will both try to create the variable `$col` in global scope and that it will do so by trying to read a variable named `df` at global scope. Neither of those are what you want.

In fact, `@eval` is not really going to help you in this particular case. More importantly, what you’re trying to do, as written, isn’t possible. You’re trying to create local variables where the number and names of those variables depends on the values inside `indexcols`. But there’s no way to do that in Julia: the _existence_ of local variables inside a function cannot depend on the values of the inputs to that function.

This seems like a case where metaprogramming is not particularly helpful. Instead, why not just construct a `Dict{Symbol, Whatever}` and fill that dict?

---

<div class="post-metadata">

**Author:** ![versipellis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/versipellis/32/7878_2.png) [@versipellis](https://discourse.julialang.org/u/versipellis)\
**Post date:** [June 28, 2019, 8:29pm UTC](https://discourse.julialang.org/t/metaprogramming-variable-scope/25819/3 "2019-06-28T20:29:06Z")

</div>

This was very insightful, and clears up a number of questions I had surrounding `eval`. After thinking on your suggestion of using `Dict{Symbol, <something>}`, I ended up with a working solution just using Base.Iterators. Thank you so much for your help!
