# Julia learning macros / metaprogramming

**URL:** https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753
**Category:** New to Julia
**Tags:** macros, metaprogramming, tutorials
**Created:** [August 29, 2020, 4:33pm UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753 "2020-08-29T16:33:34Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)
#### Post date: [August 29, 2020, 4:33pm UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/1 "2020-08-29T16:33:34Z")

</div>

Hey Julianers,

I am trieing to understand the julia macros, but I just can’t understand when do I have to use esc, quote, $, eval or so…

Can someone give me the easiest tutorial I can understand? How do you know when to use what?

It would be really nice to have an easier explaination of every command there, to catch the flow. 🙂

---

<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: [August 29, 2020, 4:58pm UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/2 "2020-08-29T16:58:21Z")

</div>

The manual is great for this: [Metaprogramming · The Julia Language](https://docs.julialang.org/en/v1/manual/metaprogramming/)

---

<div class="post-metadata">

### Author: ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)
#### Post date: [August 29, 2020, 5:05pm UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/3 "2020-08-29T17:05:34Z")

</div>

Heres a short overview.  
Note: I wrote this on my phone and haven’t been able to test it so there may be some bugs in the sample code.

`quote` or `:( )`  
Use it for constructing blocks of code.  
edit: added missing `esc`

```julia
macro shared_fields()
  esc(quote
    field1::Int
    field2::Float64
  end)
end

struct astruct
  @shared_fields()
  field3::Uint
end

struct bstruct
  @shared_fields()
  field3::String
end

```

`$`  
Splices in code

```julia
macro double_input(fn, x)
  quote
    # If x is an expression with side effects like `print(b)`
    # we don't want to do that twice so we assign it to `z` first.
    z = $(x)
    $(fn)(z, z)
  end
end

@double_input div 3
# returns 1

```

`esc`  
Use it for variables assigned to in macros that you want visible externally

```julia
macro setvar(x, y)
  quote
    $(esc(x)) = $(y)
  end
end

```

`Meta.quot`  
Allows you to splice in code without interpolating it.

```julia
macro print_code(x)
  :(println($(Meta.quot(x))))
end

```

`eval`  
Shouldn’t be used in macros or functions for the most part. It can be however useful to use at top level if you have a large number of similar functions to define.

```julia
struct MyType
  x::Int64
end

for op in [:(+), :(-), :(*), :(/)]
  @eval Base.$(op)(x::MyType, y::MyType) = MyType($(op)(x.x, y.x))
end

```

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [August 29, 2020, 5:18pm UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/4 "2020-08-29T17:18:02Z")

</div>

If you google “julia metaprogramming tutorial” you will find [this 2018 workshop](https://www.youtube.com/watch?v=SeqAQHKLNj4) by @andyferris. See also [my 2019 talk on why you shouldn’t use metaprogramming most of the time](https://www.youtube.com/watch?v=mSgXWpvQEHE).

---

<div class="post-metadata">

### Author: ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)
#### Post date: [August 29, 2020, 5:29pm UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/5 "2020-08-29T17:29:37Z")

</div>

I wrote two macros tutorials at [https://github.com/johnmyleswhite/julia\_tutorials/](https://github.com/johnmyleswhite/julia_tutorials/)

---

<div class="post-metadata">

### Author: ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)
#### Post date: [August 30, 2020, 6:56am UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/6 "2020-08-30T06:56:39Z")

</div>

Wow guys, these personal macro tutorials and workshop are awesome!

Thank you!

---

<div class="post-metadata">

### Author: ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)
#### Post date: [August 30, 2020, 7:04am UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/7 "2020-08-30T07:04:42Z")

</div>

I also have a couple of tutorials:

> **[GitHub - dpsanders/intermediate\_julia\_2019](https://github.com/dpsanders/intermediate_julia_2019)**
>
> Contribute to dpsanders/intermediate\_julia\_2019 development by creating an account on GitHub.

and

[![](https://global.discourse-cdn.com/julialang/original/3X/0/c/0c5d4206e7cb0edfebc8811c184de003bc218dbc.jpeg "JuliaCon 2016 | Intermediate Level Julia (Workshop) | David Sanders") ](https://www.youtube.com/watch?v=rAxzR7lMGDM)

The video is from 2016 so some syntax has changed, but most of the metaprogramming section is still valid.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [August 31, 2020, 6:50pm UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/8 "2020-08-31T18:50:11Z")

</div>

> [@WschW](#):
>
> ```julia
> macro shared_fields()
> quote
> field1::Int
> field2::Float64
> end
> end
> 
> struct astruct
> @shared_fields()
> field3::Uint
> end
> 
> ```

This particular example does not work:

```julia
ERROR: syntax: field name "Main.field1" is not a symbol around REPL[2]:1
Stacktrace:
 [1] top-level scope at REPL[2]:1

```

I was using `eval` for something similar, but it seems that if a macro could be used for that, it would be better. What is the best way to share fields between structs?

---

<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: [August 31, 2020, 7:05pm UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/9 "2020-08-31T19:05:19Z")

</div>

I’d encourage you to read about [macro hygeine](https://docs.julialang.org/en/v1.6-dev/manual/metaprogramming/#Hygiene) to see what’s going on here:

```julia
julia> macro shared_fields()
         ex = quote
           field1::Int
           field2::Float64
         end
         esc(ex)
       end
@shared_fields (macro with 1 method)

julia> struct astruct
         @shared_fields()
         field3::UInt
       end

julia> fieldnames(astruct)
(:field1, :field2, :field3)

```

The macro `@macroexpand` is also quite useful for debugging these things:

```julia
julia> macro shared_fields1()
           quote
               field1::Int
               field2::Float64
           end
       end
@shared_fields1 (macro with 1 method)

julia> macro shared_fields2()
           quote
               field1::Int
               field2::Float64
           end |> esc
       end
@shared_fields2 (macro with 1 method)

julia> @macroexpand @shared_fields1
quote
    #= REPL[13]:3 =#
    Main.field1::Main.Int
    #= REPL[13]:4 =#
    Main.field2::Main.Float64
end

julia> @macroexpand @shared_fields2
quote
    #= REPL[14]:3 =#
    field1::Int
    #= REPL[14]:4 =#
    field2::Float64
end

```

---

<div class="post-metadata">

### Author: ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)
#### Post date: [August 31, 2020, 7:08pm UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/10 "2020-08-31T19:08:09Z")

</div>

Yep, it was missing an `esc` I have gone back and updated the example and added a note that it was edited.

---

<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: [August 31, 2020, 7:18pm UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/11 "2020-08-31T19:18:10Z")

</div>

I just realized there was actually a mistake in that section of the documentation that I linked to so I edited my comment to use the 1.6-dev docs that have fixed the mistake. @lmiq , you may want to use the updated link so it makes more sense.

---

<div class="post-metadata">

### Author: ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)
#### Post date: [August 31, 2020, 9:27pm UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/12 "2020-08-31T21:27:11Z")

</div>

I think these contents are actually very useful for anyone who wants to understand the julia macros.  
Don’t you guys think we should collect the resources at the end of the [https://docs.julialang.org/en/v1/manual/metaprogramming/](https://docs.julialang.org/en/v1/manual/metaprogramming/)?  
And by time someone will definitely group these information and provide some extension to the understanding of the topic?

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [August 31, 2020, 9:55pm UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/13 "2020-08-31T21:55:22Z")

</div>

I thought many times that we should have a “Julia by examples” docs, built from community experiences. To be sincere, I have read many times the docs as they are, for example this metaprogramming section, and I have a hard time understanding what those things are for. I am not a computer scientist, and most times I only get the idea of what the experts are trying to explain after seeing a few examples of the functions in different contexts. After I understand how things work, when I read the docs again, I find that they are most of the time perfectly written, but a dedicated docs only for examples would be a great addition. This is how we do for plots, isn’t it?

On the other hand, perhaps the search history of this same discourse is going to achieve that goal.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [September 1, 2020, 8:48am UTC](https://discourse.julialang.org/t/julia-learning-macros-metaprogramming/45753/14 "2020-09-01T08:48:17Z")

</div>

> [@lmiq](#):
>
> I have read many times the docs as they are, for example this metaprogramming section, and I have a hard time understanding what those things are for.

I think the manual, and particularly that section, would benefit a lot from more examples, practical tips, common use cases, pitfalls.

Incremental additions are great, but I hope one of these days someone knowledgeable about Julia’s metaprogramming will sit down and do a major rewrite. I used Common Lisp macros extensively for years, but I still think of Julia’s macros as a minefield.
