# How to print human-readable macro expansion?

**URL:** https://discourse.julialang.org/t/how-to-print-human-readable-macro-expansion/67518
**Category:** General Usage
**Tags:** macros
**Created:** [September 1, 2021, 4:47pm UTC](https://discourse.julialang.org/t/how-to-print-human-readable-macro-expansion/67518 "2021-09-01T16:47:03Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)
#### Post date: [September 1, 2021, 4:47pm UTC](https://discourse.julialang.org/t/how-to-print-human-readable-macro-expansion/67518/1 "2021-09-01T16:47:03Z")

</div>

Sometimes I’d like to check what a macro is doing, by displaying its expansion. For simple cases, this is not a problem:

```julia
julia> @macroexpand(@assert 0<1)
:(if 0 < 1
      nothing
  else
      Base.throw(Base.AssertionError("0 < 1"))
  end)

```

The output is very understandable here. But when I try to expand the `@enum` macro, the output seems completely incomprehensible:

```julia
julia> Base.remove_linenums!(
           @macroexpand(@enum Fruit apple)
       )
:($(Expr(:toplevel, :(#= Enums.jl:190 =#), quote
    $(Expr(:meta, :doc))
    primitive type Fruit <: Base.Enums.Enum{Int32} 32 end
end, :(#= Enums.jl:191 =#), :(function Fruit(var"#3#x"::Base.Enums.Integer)
      (0 Base.Enums.:<= var"#3#x" Base.Enums.:<= 0) || Base.Enums.enum_argument_error(:Fruit, var"#3#x")
      return Base.Enums.bitcast(Fruit, Base.Enums.convert(Int32, var"#3#x"))
  end), :(#= Enums.jl:195 =#), :((Base.Enums.Enums).namemap(::Base.Enums.Type{Fruit}) = begin
          Dict{Int32, Symbol}(0 => :apple)
      end), :(#= Enums.jl:196 =#), :((Base.Enums.Base).typemin(var"#5#x"::Base.Enums.Type{Fruit}) = begin
          Fruit(0)
      end), :(#= Enums.jl:197 =#), :((Base.Enums.Base).typemax(var"#6#x"::Base.Enums.Type{Fruit}) = begin
          Fruit(0)
      end), :(#= Enums.jl:198 =#), :(let var"#1#insts" = (Base.Enums.Any[Fruit(var"#2#v") for var"#2#v" = Int32[0]]...,)
      (Base.Enums.Base).instances(::Base.Enums.Type{Fruit}) = begin
              var"#1#insts"
          end
  end), :(const apple = Fruit(0)), :(Base.Enums.nothing))))

```

Is there some way to understand the code above? Generally, is it possible to print macro expansions in a form that looks like human-authored source code, e.g. if you want to directly insert the expanded code into a source file?

---

<div class="post-metadata">

### Author: ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)
#### Post date: [September 1, 2021, 4:58pm UTC](https://discourse.julialang.org/t/how-to-print-human-readable-macro-expansion/67518/2 "2021-09-01T16:58:31Z")

</div>

The code is often better to read/comprehend:

```julia
julia> @less @enum Fruit apple
macro enum(T::Union{Symbol,Expr}, syms...)
    if isempty(syms)
        throw(ArgumentError("no arguments given for Enum $T"))
    end
    basetype = Int32
    ...

```

You can also open the source file:

```julia
julia> @which @enum Fruit apple
var"@enum"( __source__ ::LineNumberNode, __module__ ::Module, T::Union{Expr, Symbol}, syms...)
 in Base.Enums at Enums.jl:123

```

with an editor of your choice.

---

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [September 1, 2021, 6:23pm UTC](https://discourse.julialang.org/t/how-to-print-human-readable-macro-expansion/67518/3 "2021-09-01T18:23:15Z")

</div>

`MacroTools.@expand` was written to help with this problem IIUC, but I find it’s choice of variable names more confusing than the `var"#3#x"` etc. of `@macroexpand`. Give it a try and see if you prefer it.

---

<div class="post-metadata">

### Author: ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)
#### Post date: [September 1, 2021, 7:17pm UTC](https://discourse.julialang.org/t/how-to-print-human-readable-macro-expansion/67518/4 "2021-09-01T19:17:53Z")

</div>

That’s nice to know, but `MacroTools.@expand(@enum Fruit apple)` still generates rather complicated output. One issue is that there are nested quoted expressions, but `Base.remove_linenums!` does not recursively descends into inner levels to remove the line number information that clutters the output.

---

<div class="post-metadata">

### Author: ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)
#### Post date: [September 1, 2021, 8:10pm UTC](https://discourse.julialang.org/t/how-to-print-human-readable-macro-expansion/67518/5 "2021-09-01T20:10:59Z")

</div>

Maybe `prettify` from MacroTools can help?

---

<div class="post-metadata">

### Author: ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)
#### Post date: [September 1, 2021, 8:45pm UTC](https://discourse.julialang.org/t/how-to-print-human-readable-macro-expansion/67518/6 "2021-09-01T20:45:10Z")

</div>

Thanks, `MacroTools.prettify` works wonderfully! All the clutter has been removed, and variables have been renamed to look sane (and cute). I still have questions about the actual code generated by expanding `@enum` (maybe I should do this in a new thread). I see a sub-expression,

```julia
quote
    $(Expr(:meta, :doc))
    primitive type Fruit <: Base.Enums.Enum{Int32} 32 end
end

```

What’s the meaning of `$(Expr(:meta, :doc))`? Is this some kind of docstring for the enum?
