# Proposal: Add to Julia a macro to make operations between elements of structures easier

**URL:** <https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837>\
**Category:** Internals & Design\
**Created:** [August 21, 2018, 3:51pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837 "2018-08-21T15:51:16Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [August 21, 2018, 3:51pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/1 "2018-08-21T15:51:16Z")

</div>

Hi guys,

I would like to propose a macro to be added to Julia to make the operations between elements of structures easier.

For example, let’s say you have a structure with lots of fields called `Configurations`. Like:

```julia
struct Configuration{T}
    a::T
    b::T
    c::T
    d::T
    ...
end

```

Then, you need to compute some variables that depends on the values inside this structure. I can do something like:

```julia
conf.a * exp( - (conf.b)^2 / (conf.c) )

```

However, wouldn’t it be nice if we can have a macro in Julia to do something like:

```julia
@instruct conf a*exp( -b^2/c )

```

and it automatically replace all variables to the ones in the struct `conf`?

I know we have Parameters.jl, but this is something more simple.

What do you think?

---

<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:** [August 21, 2018, 4:19pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/2 "2018-08-21T16:19:42Z")

</div>

The nice thing about macros is that there’s no particular reason they need to live in Julia itself–you can always just make your own package to define the macro and then anyone who wants it can use it.

That said, I’m not sure what you’re asking for is possible. Even in the example you gave, how would the macro know that `a` and `b` are fields of `conf`, but `exp` is not? The macro just sees them all as symbols. You’d have to also pass the set of symbols to be extracted, something like: `@instruct(conf, (a, b, c), a * exp(-b^2/c))`

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [August 21, 2018, 4:25pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/3 "2018-08-21T16:25:35Z")

</div>

Hum OK!

I actually have no idea how this can be done, just thought it should be nice 🙂

The macro can use the `fieldnames` and if a symbol belong to it, then replace by `getfield`. Is it possible?

---

<div class="post-metadata">

**Author:** ![favba](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/favba/32/2735_2.png) [@favba](https://discourse.julialang.org/u/favba)\
**Post date:** [August 21, 2018, 4:34pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/4 "2018-08-21T16:34:50Z")

</div>

The macro sees only the `:conf` symbol. It doesn’t know it is referencing a `Configuration{T}` type.  
`fieldnames` would be called on a `symbol` not on the instance of a `Configuration` type.

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [August 21, 2018, 4:36pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/5 "2018-08-21T16:36:24Z")

</div>

Hum, maybe a `@generated` function?

---

<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:** [August 21, 2018, 4:48pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/6 "2018-08-21T16:48:30Z")

</div>

An `@generated` function would have access to the type, so you could conceivably operate on its `fieldnames()`, yes. But which function should be generated? You’d have to make every function that wants to use this feature an `@generated` one.

Or, you could just use `Parameters.jl` and do:

```julia
@unpack a, b, c = conf
a * exp(-b ^2 / c)

```

which already works 🙂

---

<div class="post-metadata">

**Author:** ![purplishrock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/purplishrock/32/13451_2.png) [@purplishrock](https://discourse.julialang.org/u/purplishrock)\
**Post date:** [August 21, 2018, 4:55pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/7 "2018-08-21T16:55:37Z")

</div>

what’s old is new again ! you want the semantics of the Pascal “with” statement.

```julia
conf = Configuration(1,2,3,4)

@with conf
  x = a * b + c * d
end

```

or even

```julia
@with conf
  a= 1
  b= 2
  c= 3
  d= 4
end

```

It seems like it should be very possible to define something like that.  
After all, Pascal could do it…

Here’s a nice example of how the “with” statement works

[https://freepascal.org/docs-html/ref/refsu62.html](https://freepascal.org/docs-html/ref/refsu62.html)

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [August 21, 2018, 6:08pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/8 "2018-08-21T18:08:37Z")

</div>

I knew I have already used this! 😃

---

<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:** [August 21, 2018, 7:08pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/9 "2018-08-21T19:08:53Z")

</div>

At type construction of `Conf` a macro `@with_Conf` could be defined, similarly to the `@unpack_Conf` macro which Parameters.jl defines. And then:

```julia
@with_Conf
  x = a * b + c * d
end`

```

However, as with `@unpack_Conf` there are pitfalls, say:

```julia
@with_Conf
  x = sin(pi*a)
end`

```

And then years later you change the `Conf` type to contain a field `pi` and now above code does something else…

---

<div class="post-metadata">

**Author:** ![Juser](https://avatars.discourse-cdn.com/v4/letter/j/34f0e0/32.png) [@Juser](https://discourse.julialang.org/u/Juser)\
**Post date:** [August 21, 2018, 7:28pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/10 "2018-08-21T19:28:14Z")

</div>

Someone may have mentioned this, but it may be worth checking out Parameters.jl. It doesn’t do exactly what you want, but it does similar things that save quite a bit of coding time.

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [August 21, 2018, 8:33pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/11 "2018-08-21T20:33:12Z")

</div>

I actually use Parameters.jl a lot! 🙂 This is more simple.

The suggestion of @mauro3 is very good indeed, and I think Parameters.jl is a good place to put such feature if @mauro3 allows.

---

<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:** [August 21, 2018, 8:33pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/12 "2018-08-21T20:33:45Z")

</div>

PR welcome 😉

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [August 21, 2018, 8:34pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/13 "2018-08-21T20:34:29Z")

</div>

I will do my best and send you a PR 🙂

---

<div class="post-metadata">

**Author:** ![tshort](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tshort/32/43_2.png) [@tshort](https://discourse.julialang.org/u/tshort)\
**Post date:** [August 21, 2018, 8:45pm UTC](https://discourse.julialang.org/t/proposal-add-to-julia-a-macro-to-make-operations-between-elements-of-structures-easier/13837/14 "2018-08-21T20:45:13Z")

</div>

DataFramesMeta (and a few other packages) do something similar by using Symbols as markers, so it’d become something like:

```julia
@with(x, :a * exp(-:b ^2 / :c))
@with x begin
       z = :a * exp(-:b ^2 / :c)
end

```
