# Boilerplate code generation by evaluation of parsed strings

**URL:** <https://discourse.julialang.org/t/boilerplate-code-generation-by-evaluation-of-parsed-strings/9326>\
**Category:** General Usage\
**Created:** [February 25, 2018, 11:59pm UTC](https://discourse.julialang.org/t/boilerplate-code-generation-by-evaluation-of-parsed-strings/9326 "2018-02-25T23:59:25Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![colintbowers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/colintbowers/32/8033_2.png) [@colintbowers](https://discourse.julialang.org/u/colintbowers)\
**Post date:** [February 25, 2018, 11:59pm UTC](https://discourse.julialang.org/t/boilerplate-code-generation-by-evaluation-of-parsed-strings/9326/1 "2018-02-25T23:59:25Z")

</div>

Hi all,

The following is a trivial MWE of something I find myself doing sometimes in my code: I define some new struct

```julia
struct M
    x::Float64
    y::String
end

```

and I want to build accessor functions for getting the fields from an instance of the type. Rather than two lines of code, I use one line, exploiting common features of both functions:

`[eval(parse("get$(fn)(m::M) = m.$(fn)")) for fn in ["x", "y"] ]`

Two questions (from someone who doesn’t really understand meta-programming):

**1)** Is there anything wrong with writing code like this? My understanding is that it is both safe and performant, since I’m not evaling any user generated strings, just my own code (so it is safe), and all the evaling is happening at compile time (so it is performant). Is this understanding correct?

**2)** The examples from the docs (e.g. the section on code-generation) all tend to use the `@eval` macro for code generation, rather than parsing and evaling strings like I have done above. I can’t for the life of me see how I would write the above code using the `@eval` macro (but I really am new to this stuff). The main issue is that I’m not extending existing function names, so I feel like I need to use the string interpolation trick in order to get the function names that I want and simultaneously reference the fields that I’m interested in, but no doubt there is a simple and obvious way around this issue. Could anyone re-write my above MWE but using the `@eval` macro? That might be all I need to get past this mental obstacle (and hopefully I’ll be able to generalise to more complicated real-world use-cases).

Thanks in advance to all responders,

Colin

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [February 26, 2018, 12:50am UTC](https://discourse.julialang.org/t/boilerplate-code-generation-by-evaluation-of-parsed-strings/9326/2 "2018-02-26T00:50:35Z")

</div>

> [@colintbowers](#):
>
> My understanding is that it is both safe and performant, since I’m not evaling any user generated strings, just my own code (so it is safe), and all the evaling is happening at compile time (so it is performant).

It’s safe but it’s a bad habbit that can lead to unsafe code in the future.  
If you treat the evaluation of the whole thing as compile time then there won’t be any code that has any performance issue. If you don’t treat the whole code as compile time than no it’s not performant.

> [@colintbowers](#):
>
> all tend to use the `@eval` macro for code generation,

`@eval` is equivalent to `eval`

> [@colintbowers](#):
>
> rather than parsing and evaling strings

Correct. Parsing a string should never be done for metaprogramming. Except when you need to workaround parser difference between julia versions (though I wouldn’t call this usecase metaprogramming…).

> [@colintbowers](#):
>
> so I feel like I need to use the string interpolation trick in order to get the function names

Correct, you do need string interpolation, but you do not need to and should not parse the interpolated string.

> [@colintbowers](#):
>
> I can’t for the life of me see how I would write the above code using the `@eval` macro (but I really am new to this stuff)

```julia
@eval $(Symbol("get$fn"))(m::M) = m.$fn

```

As a side note, don’t use comprehension as loops.

---

<div class="post-metadata">

**Author:** ![colintbowers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/colintbowers/32/8033_2.png) [@colintbowers](https://discourse.julialang.org/u/colintbowers)\
**Post date:** [February 26, 2018, 1:01am UTC](https://discourse.julialang.org/t/boilerplate-code-generation-by-evaluation-of-parsed-strings/9326/3 "2018-02-26T01:01:10Z")

</div>

Wonderful and comprehensive answer, thank you very much! One quick question:

> [@yuyichao](#):
>
> As a side note, don’t use comprehension as loops.

Could you elaborate on this? I thought a comprehension was just a shorthand notation for a loop…

Thanks again.

Colin

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [February 26, 2018, 1:02am UTC](https://discourse.julialang.org/t/boilerplate-code-generation-by-evaluation-of-parsed-strings/9326/4 "2018-02-26T01:02:16Z")

</div>

> [@colintbowers](#):
>
> just a shorthand notation for a loop

It creates an array of useless results. Also, it’s really not much shorter than `for x in y; f(x); end`

---

<div class="post-metadata">

**Author:** ![colintbowers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/colintbowers/32/8033_2.png) [@colintbowers](https://discourse.julialang.org/u/colintbowers)\
**Post date:** [February 26, 2018, 1:03am UTC](https://discourse.julialang.org/t/boilerplate-code-generation-by-evaluation-of-parsed-strings/9326/5 "2018-02-26T01:03:08Z")

</div>

Understood. Thank you.

Colin
