# Meta-programming, structure constructor definition

**URL:** <https://discourse.julialang.org/t/meta-programming-structure-constructor-definition/23811>\
**Category:** New to Julia\
**Tags:** metaprogramming, data\_structures\
**Created:** [May 3, 2019, 12:45pm UTC](https://discourse.julialang.org/t/meta-programming-structure-constructor-definition/23811 "2019-05-03T12:45:08Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![gdestouet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdestouet/32/6175_2.png) [@gdestouet](https://discourse.julialang.org/u/gdestouet)\
**Post date:** [May 3, 2019, 12:45pm UTC](https://discourse.julialang.org/t/meta-programming-structure-constructor-definition/23811/1 "2019-05-03T12:45:08Z")

</div>

Hello everyone,

I was playing around with Meta-programming and I was wondering if it is possible to facilitate writing long constructor call for a structure with many fields .

Suppose I have

```julia
struct s_example
     arg_1
     arg_2
      ...
     arg_N
end

```

With a constructor

```julia
function define_s(parameters)
     arg_1 = f(parameters)
      ...
     arg_N = g(parameters)
     object = s_example(arg_1,...,arg_N)
     return object
end

```

Is it possible to make the call to s\_example easier with metaprogramming ?  
I tried this

```julia
function define_s_easen(parameters)
    arg_1 = f(parameters)
     ...
    arg_N = g(parameters)
    object = eval(Expr(:call,s_example,fieldnames(s_example)...))
    return object
end

```

But since eval look for `arg_i` in the global scope, we get `arg_1 not defined`. During compilation, how can I write the function to be defined as the trivial one `define_s` ?

( Or maybe It is an equivalent problem, is there a way in Julia to return all the variable defined inside a function ? )

Thank you in advance,  
GD

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [May 3, 2019, 12:51pm UTC](https://discourse.julialang.org/t/meta-programming-structure-constructor-definition/23811/2 "2019-05-03T12:51:08Z")

</div>

You need to construct the entire function `define_s_easen` as expression and eval that.

---

<div class="post-metadata">

**Author:** ![gdestouet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdestouet/32/6175_2.png) [@gdestouet](https://discourse.julialang.org/u/gdestouet)\
**Post date:** [May 3, 2019, 1:19pm UTC](https://discourse.julialang.org/t/meta-programming-structure-constructor-definition/23811/4 "2019-05-03T13:19:34Z")

</div>

I dont really see how to do that, I dont know how to broadcast the interpolation for symbols inside `fieldnames`.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [May 3, 2019, 1:21pm UTC](https://discourse.julialang.org/t/meta-programming-structure-constructor-definition/23811/5 "2019-05-03T13:21:58Z")

</div>

Actually, you should do:

```julia
function define_s(parameters)
     args = (f(parameters), ..., g(parameters))
     object = s_example(args...)
     return object
end

```

---

<div class="post-metadata">

**Author:** ![gdestouet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdestouet/32/6175_2.png) [@gdestouet](https://discourse.julialang.org/u/gdestouet)\
**Post date:** [May 3, 2019, 1:25pm UTC](https://discourse.julialang.org/t/meta-programming-structure-constructor-definition/23811/6 "2019-05-03T13:25:04Z")

</div>

I agree with this, but what about [the first solution](https://discourse.julialang.org/t/meta-programming-structure-constructor-definition/23811/2) you proposed ?

Because we lose some readability for the proper definition of each `arg_i`, what we dont really care about is the call `s_example(arg_1,arg_2, etc...)`

( And actually we dont necessarily have functions `f(parameters)`, it was just a way to simplify the example )

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [May 3, 2019, 1:46pm UTC](https://discourse.julialang.org/t/meta-programming-structure-constructor-definition/23811/7 "2019-05-03T13:46:33Z")

</div>

Something like

```julia
fld = fieldnames(s_example)
fns = [:f, :g]
calls = quote end
for (f,fn) in zip(fld,fns)
  push!(calls.args, :($f = $fn(parameters)))
end
eval(quote
function define_s_easen(parameters)
  $calls
  return s_example($(fld...))
end
end)

```

PS: you sound like you should look at `Base.@kwdef` or Parameters.jl

---

<div class="post-metadata">

**Author:** ![gdestouet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdestouet/32/6175_2.png) [@gdestouet](https://discourse.julialang.org/u/gdestouet)\
**Post date:** [May 3, 2019, 1:56pm UTC](https://discourse.julialang.org/t/meta-programming-structure-constructor-definition/23811/8 "2019-05-03T13:56:27Z")

</div>

Nice ! Thank you very much, I didn’t know about `Base.@kwdef` and `Parameters.jl`, I just checked it out and it is indeed exactly what I need !
