# Module Generation from macros

**URL:** https://discourse.julialang.org/t/module-generation-from-macros/2555
**Category:** General Usage
**Created:** [March 9, 2017, 4:04am UTC](https://discourse.julialang.org/t/module-generation-from-macros/2555 "2017-03-09T04:04:39Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![mbeltagy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbeltagy/32/130_2.png) [@mbeltagy](https://discourse.julialang.org/u/mbeltagy)
#### Post date: [March 9, 2017, 4:04am UTC](https://discourse.julialang.org/t/module-generation-from-macros/2555/1 "2017-03-09T04:04:39Z")

</div>

I am trying to generate modules using a macro, but it keeps failing. I am not sure how to handle this.  
EG.

```julia
julia> macro mymodule(name)
                quote
                  module ($name)
                  end
                end
              end
@mymodule (macro with 1 method)

julia> @mymodule Foo
ERROR: syntax: module expression not at top level

```

So Julia does not seem to want to accept this. However, I found and closed issues on that very same topic  
[https://github.com/JuliaLang/julia/issues/1200](https://github.com/JuliaLang/julia/issues/1200)

---

<div class="post-metadata">

### Author: ![fengyang.wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fengyang.wang/32/104_2.png) [@fengyang.wang](https://discourse.julialang.org/u/fengyang.wang)
#### Post date: [March 9, 2017, 7:47am UTC](https://discourse.julialang.org/t/module-generation-from-macros/2555/2 "2017-03-09T07:47:12Z")

</div>

You can `@eval` the `module` to get around this.

```julia
julia> macro mymodule(name)
           quote
               @eval module $(esc(name))
               end
           end
       end
@mymodule (macro with 1 method)

julia> @mymodule Foo
Foo

julia> Foo
Foo

```

---

<div class="post-metadata">

### Author: ![MikeInnes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikeinnes/32/3656_2.png) [@MikeInnes](https://discourse.julialang.org/u/MikeInnes)
#### Post date: [March 9, 2017, 12:03pm UTC](https://discourse.julialang.org/t/module-generation-from-macros/2555/3 "2017-03-09T12:03:02Z")

</div>

Try:

```julia
macro mymodule(name)
  Expr(:toplevel,
    :(module ($name)
      end))
end

```

---

<div class="post-metadata">

### Author: ![mbeltagy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbeltagy/32/130_2.png) [@mbeltagy](https://discourse.julialang.org/u/mbeltagy)
#### Post date: [March 9, 2017, 2:30pm UTC](https://discourse.julialang.org/t/module-generation-from-macros/2555/4 "2017-03-09T14:30:29Z")

</div>

@fengyang.wang Thank you! Your solution worked very nicely.  
@MikeInnes Your solution worked for 0.5, but not 0.6, I am not sure why.

---

<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: [March 9, 2017, 2:35pm UTC](https://discourse.julialang.org/t/module-generation-from-macros/2555/5 "2017-03-09T14:35:50Z")

</div>

The `name` (and in general, all user inputs) has to be `esc`aped.

---

<div class="post-metadata">

### Author: ![moesphere](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/moesphere/32/3348_2.png) [@moesphere](https://discourse.julialang.org/u/moesphere)
#### Post date: [July 30, 2020, 1:59pm UTC](https://discourse.julialang.org/t/module-generation-from-macros/2555/6 "2020-07-30T13:59:56Z")

</div>

Does someone know why the first macro works and the second fails?

```julia
macro mymodule(name)
    modname = esc(name)
    return :(module $modname end)
end
@mymodule MyMod

```

Works. And the second, using a `quote` block does not throwing `ERROR: syntax: "module" expression not at top level` (see also [https://github.com/JuliaLang/julia/issues/1200](https://github.com/JuliaLang/julia/issues/1200)):

```julia
macro mymodule(name)
    modname = esc(name)
    return quote module $modname end end
end
@mymodule MyMod

```

---

<div class="post-metadata">

### Author: ![mbeltagy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbeltagy/32/130_2.png) [@mbeltagy](https://discourse.julialang.org/u/mbeltagy)
#### Post date: [July 30, 2020, 9:25pm UTC](https://discourse.julialang.org/t/module-generation-from-macros/2555/7 "2020-07-30T21:25:30Z")

</div>

If you do a `@macroexpand` on both versions you will see that in the first instance you get something like

```julia
Expr
  head: Symbol module
  args: Array{Any}((3,))
    1: Bool true
    2: Symbol MyMod
    3: Expr
      head: Symbol block
      args: Array{Any}((2,))
        1: LineNumberNode
          line: Int64 3
          file: Symbol REPL[7]
        2: LineNumberNode
          line: Int64 3
          file: Symbol REPL[7]

```

And in the second, you get

```julia
Expr
  head: Symbol block
  args: Array{Any}((2,))
    1: LineNumberNode
      line: Int64 3
      file: Symbol REPL[12]
    2: Expr
      head: Symbol module
      args: Array{Any}((3,))
        1: Bool true
        2: Symbol MyMod
        3: Expr
          head: Symbol block
          args: Array{Any}((2,))
            1: LineNumberNode
              line: Int64 3
              file: Symbol REPL[12]
            2: LineNumberNode
              line: Int64 3
              file: Symbol REPL[12]

```

Those are clearly very different. Julia does not allow you to define `module`s inside of blocks. If it would, you can have modules defined inside `for` loops, which wouldn’t make much sense. As the error indicates, `module` declaration has to be at the top level.

The generated expression in the second case is equivalent to

```julia
begin
module MyMod
end
end

```

Which Julia will simply not allow.

---

<div class="post-metadata">

### Author: ![moesphere](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/moesphere/32/3348_2.png) [@moesphere](https://discourse.julialang.org/u/moesphere)
#### Post date: [July 31, 2020, 4:54am UTC](https://discourse.julialang.org/t/module-generation-from-macros/2555/8 "2020-07-31T04:54:44Z")

</div>

Thank you for the explanation!

---

<div class="post-metadata">

### Author: ![o314](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/o314/32/252_2.png) [@o314](https://discourse.julialang.org/u/o314)
#### Post date: [November 24, 2021, 4:29am UTC](https://discourse.julialang.org/t/module-generation-from-macros/2555/9 "2021-11-24T04:29:44Z")

</div>

Some previous forms do not work fully on v1.6. The two following ones are ok for me on Julia v1.6

```julia
macro my_mod(x)
    @assert Meta.isexpr(x, :module, 3)
    (notbare::Bool, nm::Symbol, body::Expr) = x.args
    pushfirst!(body.args, esc(:(
        export go, RES ;
        go() = "launched" ;
        const RES = "landing ok")))
    Expr(:toplevel,
        :(module $(esc(nm)); $(body.args...) end))
end
@my_mod module M1 end
using Test
@test M1.go() == "launched"
@test M1.RES == "landing ok"

```

AND

```julia
macro my_mod2(x)
    @assert Meta.isexpr(x, :module, 3)
    (notbare::Bool, nm::Symbol, body::Expr) = x.args
    pushfirst!(body.args, esc(:(
        export go, RES ;
        go() = "launched" ;
        const RES = "landing ok")))
    Expr(:toplevel,
        Expr(:module, notbare, esc(nm), body))
end
@my_mod2 module M2 end
using Test
@test M2.go() == "launched"
@test M2.RES == "landing ok"

```
