# Use @eval within a function

**URL:** <https://discourse.julialang.org/t/use-eval-within-a-function/40451>\
**Category:** General Usage\
**Tags:** metaprogramming, syntax\
**Created:** [May 30, 2020, 1:51am UTC](https://discourse.julialang.org/t/use-eval-within-a-function/40451 "2020-05-30T01:51:49Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lucas\_Liu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucas_liu/32/9731_2.png) [@Lucas\_Liu](https://discourse.julialang.org/u/Lucas_Liu)\
**Post date:** [May 30, 2020, 1:51am UTC](https://discourse.julialang.org/t/use-eval-within-a-function/40451/1 "2020-05-30T01:51:50Z")

</div>

I am new to metaprograming in Julia. The case is I have many vectors to initialize in a constructor. I came up with this code

```julia
function MyStruct(n::Int)
    vecs = [:x, :y, :z, :p]
    for v in vecs
        @eval $v = Vector{Float64}(undef, $n)
    end
    return @eval MyStruct($(vecs...))
end
```

Then I found that @eval is always evaluated in the module’s global scope. It is not a good idea to use @eval within a function. It can be performance killer. Also, @eval does not have scope to the local variable `n`, so I have to do interpolation, adding `$` to every local variable in my function.

Any suggestions for the correct way of replacing repeated vector initialization within a constructor function?

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [May 30, 2020, 2:02am UTC](https://discourse.julialang.org/t/use-eval-within-a-function/40451/2 "2020-05-30T02:02:23Z")

</div>

Doesn’t seem to require macros. Try

```julia
function MyStruct(n::Int)
    vecs = [:x, :y, :z, :p]
    params = (Vector{Float64}(undef, n) for sym in vecs)
    return MyStruct(params...)
end

```

---

<div class="post-metadata">

**Author:** ![Lucas\_Liu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucas_liu/32/9731_2.png) [@Lucas\_Liu](https://discourse.julialang.org/u/Lucas_Liu)\
**Post date:** [May 30, 2020, 2:13am UTC](https://discourse.julialang.org/t/use-eval-within-a-function/40451/3 "2020-05-30T02:13:26Z")

</div>

Thank you! You are right. In this constructor case, it indeed doesn’t require macros. And seems like we don’t even need to define ` vecs ` if not for readability. A follow up question, in a another case, I want to assign vectors to a list of fields in a struct

```julia
mutable struct NewStruct
    x::Vector{Float64}
    y::Vector{Float64}
    z::Vector{Float64}
    p::Vector{Float64}
    NewStruct() = new()
end

function init(a::NewStruct)
    vecs = [:x, :y, :z, :p]
    for v in vecs
        @eval a.$v = zeros(10)
    end
end
```

Any idea how to use macro for this case?

---

<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:** [May 30, 2020, 2:26am UTC](https://discourse.julialang.org/t/use-eval-within-a-function/40451/4 "2020-05-30T02:26:36Z")

</div>

You don’t need a macro or `eval()` in this case. You can just use the `setproperty!` function which already does what you want:

```julia

julia> function init(a::NewStruct)
           vecs = [:x, :y, :z, :p]
           for v in vecs
               setproperty!(a, v, zeros(10))
           end
       end
init (generic function with 1 method)

julia> init(NewStruct())

```

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [May 30, 2020, 2:41am UTC](https://discourse.julialang.org/t/use-eval-within-a-function/40451/5 "2020-05-30T02:41:58Z")

</div>

As others have pointed out, this can easily be done without any meta-programming and in general, metaprogramming is just the wrong tool for this job. However, if you’re interested in learning about metaprogramming, it is often useful to learn it with simple cases like this rather than with something complicated.

The tool you want for this is called a macro. I’d strongly recommend reading this section of the documentation: [Metaprogramming · The Julia Language](https://docs.julialang.org/en/v1/manual/metaprogramming/index.html). It’s very well written and useful.
