# Macro expansion and evaluation when the module with the macro definition is not in scope

**URL:** <https://discourse.julialang.org/t/macro-expansion-and-evaluation-when-the-module-with-the-macro-definition-is-not-in-scope/119170>\
**Category:** General Usage\
**Tags:** macros\
**Created:** [September 7, 2024, 3:25pm UTC](https://discourse.julialang.org/t/macro-expansion-and-evaluation-when-the-module-with-the-macro-definition-is-not-in-scope/119170 "2024-09-07T15:25:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [September 7, 2024, 3:25pm UTC](https://discourse.julialang.org/t/macro-expansion-and-evaluation-when-the-module-with-the-macro-definition-is-not-in-scope/119170/1 "2024-09-07T15:25:42Z")

</div>

Let’s say I’m developing a macro `@mymacro` in a package called CoolStuff. Suppose that this

```julia
@mymacro 42

```

expands to this:

```julia
CoolStuff.foo(42)

```

Now suppose that the user loads `@mymacro` by doing `using CoolStuff: @mymacro` instead of `using CoolStuff`. Intuitively I would think that `@mymacro 42` would fail because the expanded code refers to the `CoolStuff` module, but the `CoolStuff` module is not actually in scope. However, when I tested it out on an existing package, it seems to work. Here’s an example with the Memoization.jl package:

```julia
julia> using Memoization: @memoize

julia> Memoization
ERROR: UndefVarError: `Memoization` not defined

julia> Memoization.get_cache
ERROR: UndefVarError: `Memoization` not defined
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

julia> @memoize f(x) = (println("Computed $x"); x)
f (generic function with 1 method)

julia> f(2)
Computed 2
2

julia> f(2)
2

```

So, in this example the `@memoize` function works fine, even though the `Memoization` module is not in scope. If we look at the expanded code for `@memoize`, we can see that the expanded code refers to `Memoization` and `Memoization.get_cache` (and various other functions internal to Memoization.jl):

> **Expanded \`@memoize\`**
>
> ```julia
> quote
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:155 =#
> var"#19#func" = begin
> $(Expr(:meta, :doc))
> function f(x::Any; )
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:206 =#
> var"##cache#231" = (Memoization.get_cache)(IdDict, f)
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:207 =#
> var"##getter#230"() = begin
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:207 =#
> begin
> #= REPL[6]:1 =#
> println("Computed $(x)")
> #= REPL[6]:1 =#
> x
> end
> end
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:208 =#
> var"##T#229" = (Core.Compiler.return_type)(var"##getter#230", (Tuple){})
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:209 =#
> (Memoization._get!)(var"##getter#230", var"##cache#231", ((x,), ()))::var"##T#229"
> end
> end
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:156 =#
> begin
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:158 =#
> local var"#20#cache_constructor_expr′" = Memoization._get!((()->begin
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:158 =#
> $(QuoteNode(IdDict))
> end), Memoization.cache_constructor_exprs, var"#19#func")
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:159 =#
> if var"#20#cache_constructor_expr′" != $(QuoteNode(IdDict))
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:160 =#
> Memoization.error("$(var"#19#func") is already memoized with $(var"#20#cache_constructor_expr′")")
> end
> end
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:163 =#
> if Memoization.statically_memoizable(Memoization.typeof(var"#19#func"))
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:168 =#
> if Memoization.which((Memoization)._static_get_cache, Memoization.Tuple{Memoization.typeof(var"#19#func")}) == Memoization.which((Memoization)._static_get_cache, Memoization.Tuple{Memoization.Any})
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:172 =#
> Core.eval(Main, Core._expr(:macrocall, Symbol("@generated"), $(QuoteNode(:(#= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:172 =#))), Core._expr(:function, Core._expr(:call, $(Expr(:copyast, :($(QuoteNode(:((Memoization)._static_get_cache)))))), Core._expr(:(::), Core._expr(:call, :typeof, var"#19#func"))), $(Expr(:copyast, :($(QuoteNode(quote
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:172 =#
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:173 =#
> (IdDict)()
> end))))))))
> end
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:180 =#
> (Memoization.empty_cache!)(f)
> end
> #= /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl:182 =#
> var"#19#func"
> end
> 
> ```

So, how does that work? Does evaluation of macro calls have some extra magic that lets Julia know where to find `Memoization.get_cache` even though `Memoization` is not in scope?

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [September 7, 2024, 4:16pm UTC](https://discourse.julialang.org/t/macro-expansion-and-evaluation-when-the-module-with-the-macro-definition-is-not-in-scope/119170/2 "2024-09-07T16:16:25Z")

</div>

It looks like there is some extra magic that you don’t see in the printout from `@macroexpand`. If you use `dump` on the expression returned by `@macroexpand` you can see more detail. So, if you do this:

```julia
ex = @macroexpand @memoize f(x) = (println("Computed $x"); x)
dump(ex; maxdepth=1000)

```

then you will see some things like this:

```julia
6: Expr
      head: Symbol if
      args: Array{Any}((2,))
        1: Expr
          head: Symbol call
          args: Array{Any}((2,))
            1: GlobalRef
              mod: Module Memoization
              name: Symbol statically_memoizable
              binding: Core.Binding
                value: statically_memoizable (function of type typeof(Memoization.statically_memoizable))
                globalref: GlobalRef#= circular reference @-2 =#
                owner: Core.Binding#= circular reference @-1 =#
                ty: Any
                flags: UInt8 0x01

```

So, that `GlobalRef` seems to be part of the magic.

There are also some entries like this:

```julia
4: Expr
  head: Symbol call
  args: Array{Any}((2,))
    1: empty_cache! (function of type typeof(Memoization.empty_cache!))
    2: Symbol f

```

Note that arg 1 has a function value, `empty_cache!`, rather than a `Symbol empty_cache!`. I didn’t realize that was allowed, but the manual says “Expressions provided by the parser generally only have symbols, other expressions, and literal values as their args, whereas expressions constructed by Julia code can have arbitrary run-time values without literal forms as args.” That might be a new addition to the manual, because I don’t remember seeing that before. That also really messes with my mental model for how macros work. I thought macros were just syntax manipulation…

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [September 7, 2024, 4:16pm UTC](https://discourse.julialang.org/t/macro-expansion-and-evaluation-when-the-module-with-the-macro-definition-is-not-in-scope/119170/3 "2024-09-07T16:16:36Z")

</div>

Here’s the full dump of the expression returned by `@macroexpand`:

> **Full dump of macroexpand**
>
> ```julia
> Expr
> head: Symbol block
> args: Array{Any}((8,))
> 1: LineNumberNode
> line: Int64 155
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 2: Expr
> head: Symbol =
> args: Array{Any}((2,))
> 1: Symbol #21#func
> 2: Expr
> head: Symbol block
> args: Array{Any}((2,))
> 1: Expr
> head: Symbol meta
> args: Array{Any}((1,))
> 1: Symbol doc
> 2: Expr
> head: Symbol function
> args: Array{Any}((2,))
> 1: Expr
> head: Symbol call
> args: Array{Any}((3,))
> 1: Symbol f
> 2: Expr
> head: Symbol parameters
> args: Array{Any}((0,))
> 3: Expr
> head: Symbol ::
> args: Array{Any}((2,))
> 1: Symbol x
> 2: Symbol Any
> 2: Expr
> head: Symbol block
> args: Array{Any}((8,))
> 1: LineNumberNode
> line: Int64 206
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 2: Expr
> head: Symbol =
> args: Array{Any}((2,))
> 1: Symbol ##cache#234
> 2: Expr
> head: Symbol call
> args: Array{Any}((3,))
> 1: get_cache (function of type typeof(Memoization.get_cache))
> 2: UnionAll
> var: TypeVar
> name: Symbol K
> lb: Union{}
> ub: Any
> body: UnionAll
> var: TypeVar
> name: Symbol V
> lb: Union{}
> ub: Any
> body: IdDict{K, V} <: AbstractDict{K, V}
> ht::Vector{Any}
> count::Int64
> ndel::Int64
> 3: Symbol f
> 3: LineNumberNode
> line: Int64 207
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 4: Expr
> head: Symbol =
> args: Array{Any}((2,))
> 1: Expr
> head: Symbol call
> args: Array{Any}((1,))
> 1: Symbol ##getter#233
> 2: Expr
> head: Symbol block
> args: Array{Any}((2,))
> 1: LineNumberNode
> line: Int64 207
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 2: Expr
> head: Symbol block
> args: Array{Any}((4,))
> 1: LineNumberNode
> line: Int64 1
> file: Symbol REPL[7]
> 2: Expr
> head: Symbol call
> args: Array{Any}((2,))
> 1: Symbol println
> 2: Expr
> head: Symbol string
> args: Array{Any}((2,))
> 1: String "Computed "
> 2: Symbol x
> 3: LineNumberNode
> line: Int64 1
> file: Symbol REPL[7]
> 4: Symbol x
> 5: LineNumberNode
> line: Int64 208
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 6: Expr
> head: Symbol =
> args: Array{Any}((2,))
> 1: Symbol ##T#232
> 2: Expr
> head: Symbol call
> args: Array{Any}((3,))
> 1: return_type (function of type typeof(Core.Compiler.return_type))
> 2: Symbol ##getter#233
> 3: Expr
> head: Symbol curly
> args: Array{Any}((1,))
> 1: Tuple <: Any
> 7: LineNumberNode
> line: Int64 209
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 8: Expr
> head: Symbol ::
> args: Array{Any}((2,))
> 1: Expr
> head: Symbol call
> args: Array{Any}((4,))
> 1: _get! (function of type typeof(Memoization._get!))
> 2: Symbol ##getter#233
> 3: Symbol ##cache#234
> 4: Expr
> head: Symbol tuple
> args: Array{Any}((2,))
> 1: Expr
> head: Symbol tuple
> args: Array{Any}((1,))
> 1: Symbol x
> 2: Expr
> head: Symbol tuple
> args: Array{Any}((0,))
> 2: Symbol ##T#232
> 3: LineNumberNode
> line: Int64 156
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 4: Expr
> head: Symbol block
> args: Array{Any}((4,))
> 1: LineNumberNode
> line: Int64 158
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 2: Expr
> head: Symbol local
> args: Array{Any}((1,))
> 1: Expr
> head: Symbol =
> args: Array{Any}((2,))
> 1: Symbol #22#cache_constructor_expr′
> 2: Expr
> head: Symbol call
> args: Array{Any}((4,))
> 1: GlobalRef
> mod: Module Memoization
> name: Symbol _get!
> binding: Core.Binding
> value: _get! (function of type typeof(Memoization._get!))
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: Any
> flags: UInt8 0x01
> 2: Expr
> head: Symbol ->
> args: Array{Any}((2,))
> 1: Expr
> head: Symbol tuple
> args: Array{Any}((0,))
> 2: Expr
> head: Symbol block
> args: Array{Any}((2,))
> 1: LineNumberNode
> line: Int64 158
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 2: QuoteNode
> value: UnionAll
> var: TypeVar
> name: Symbol K
> lb: Union{}
> ub: Any
> body: UnionAll
> var: TypeVar
> name: Symbol V
> lb: Union{}
> ub: Any
> body: IdDict{K, V} <: AbstractDict{K, V}
> ht::Vector{Any}
> count::Int64
> ndel::Int64
> 3: GlobalRef
> mod: Module Memoization
> name: Symbol cache_constructor_exprs
> binding: Core.Binding
> value: IdDict{Any, Any}
> ht: Array{Any}((32,))
> 1: #undef
> 2: #undef
> 3: #undef
> 4: #undef
> 5: #undef
> ...
> 28: #undef
> 29: #undef
> 30: #undef
> 31: #undef
> 32: #undef
> count: Int64 1
> ndel: Int64 0
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: Any
> flags: UInt8 0x01
> 4: Symbol #21#func
> 3: LineNumberNode
> line: Int64 159
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 4: Expr
> head: Symbol if
> args: Array{Any}((2,))
> 1: Expr
> head: Symbol call
> args: Array{Any}((3,))
> 1: GlobalRef
> mod: Module Memoization
> name: Symbol !=
> binding: Core.Binding
> value: #undef
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding
> value: != (function of type typeof(!=))
> globalref: GlobalRef
> mod: Module Base
> name: Symbol !=
> binding: Core.Binding#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: #undef
> flags: UInt8 0x03
> ty: #undef
> flags: UInt8 0x00
> 2: Symbol #22#cache_constructor_expr′
> 3: QuoteNode
> value: UnionAll
> var: TypeVar
> name: Symbol K
> lb: Union{}
> ub: Any
> body: UnionAll
> var: TypeVar
> name: Symbol V
> lb: Union{}
> ub: Any
> body: IdDict{K, V} <: AbstractDict{K, V}
> ht::Vector{Any}
> count::Int64
> ndel::Int64
> 2: Expr
> head: Symbol block
> args: Array{Any}((2,))
> 1: LineNumberNode
> line: Int64 160
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 2: Expr
> head: Symbol call
> args: Array{Any}((2,))
> 1: GlobalRef
> mod: Module Memoization
> name: Symbol error
> binding: Core.Binding
> value: #undef
> globalref: GlobalRef#= circular reference @-2 =#
> owner: #undef
> ty: #undef
> flags: UInt8 0x00
> 2: Expr
> head: Symbol string
> args: Array{Any}((3,))
> 1: Symbol #21#func
> 2: String " is already memoized with "
> 3: Symbol #22#cache_constructor_expr′
> 5: LineNumberNode
> line: Int64 163
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 6: Expr
> head: Symbol if
> args: Array{Any}((2,))
> 1: Expr
> head: Symbol call
> args: Array{Any}((2,))
> 1: GlobalRef
> mod: Module Memoization
> name: Symbol statically_memoizable
> binding: Core.Binding
> value: statically_memoizable (function of type typeof(Memoization.statically_memoizable))
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: Any
> flags: UInt8 0x01
> 2: Expr
> head: Symbol call
> args: Array{Any}((2,))
> 1: GlobalRef
> mod: Module Memoization
> name: Symbol typeof
> binding: Core.Binding
> value: #undef
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding
> value: typeof (function of type typeof(typeof))
> globalref: GlobalRef
> mod: Module Core
> name: Symbol typeof
> binding: Core.Binding#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: Any
> flags: UInt8 0x03
> ty: #undef
> flags: UInt8 0x00
> 2: Symbol #21#func
> 2: Expr
> head: Symbol block
> args: Array{Any}((4,))
> 1: LineNumberNode
> line: Int64 168
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 2: Expr
> head: Symbol if
> args: Array{Any}((2,))
> 1: Expr
> head: Symbol call
> args: Array{Any}((3,))
> 1: GlobalRef
> mod: Module Memoization
> name: Symbol ==
> binding: Core.Binding
> value: #undef
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding
> value: == (function of type typeof(==))
> globalref: GlobalRef
> mod: Module Base
> name: Symbol ==
> binding: Core.Binding#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: #undef
> flags: UInt8 0x03
> ty: #undef
> flags: UInt8 0x00
> 2: Expr
> head: Symbol call
> args: Array{Any}((3,))
> 1: GlobalRef
> mod: Module Memoization
> name: Symbol which
> binding: Core.Binding
> value: #undef
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding
> value: which (function of type typeof(which))
> globalref: GlobalRef
> mod: Module Base
> name: Symbol which
> binding: Core.Binding#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: #undef
> flags: UInt8 0x03
> ty: #undef
> flags: UInt8 0x00
> 2: Expr
> head: Symbol .
> args: Array{Any}((2,))
> 1: Module Memoization
> 2: QuoteNode
> value: Symbol _static_get_cache
> 3: Expr
> head: Symbol curly
> args: Array{Any}((2,))
> 1: GlobalRef
> mod: Module Memoization
> name: Symbol Tuple
> binding: Core.Binding
> value: #undef
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding
> value: Tuple <: Any
> globalref: GlobalRef
> mod: Module Core
> name: Symbol Tuple
> binding: Core.Binding#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: Any
> flags: UInt8 0x03
> ty: #undef
> flags: UInt8 0x00
> 2: Expr
> head: Symbol call
> args: Array{Any}((2,))
> 1: GlobalRef
> mod: Module Memoization
> name: Symbol typeof
> binding: Core.Binding
> value: #undef
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding
> value: typeof (function of type typeof(typeof))
> globalref: GlobalRef
> mod: Module Core
> name: Symbol typeof
> binding: Core.Binding#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: Any
> flags: UInt8 0x03
> ty: #undef
> flags: UInt8 0x00
> 2: Symbol #21#func
> 3: Expr
> head: Symbol call
> args: Array{Any}((3,))
> 1: GlobalRef
> mod: Module Memoization
> name: Symbol which
> binding: Core.Binding
> value: #undef
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding
> value: which (function of type typeof(which))
> globalref: GlobalRef
> mod: Module Base
> name: Symbol which
> binding: Core.Binding#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: #undef
> flags: UInt8 0x03
> ty: #undef
> flags: UInt8 0x00
> 2: Expr
> head: Symbol .
> args: Array{Any}((2,))
> 1: Module Memoization
> 2: QuoteNode
> value: Symbol _static_get_cache
> 3: Expr
> head: Symbol curly
> args: Array{Any}((2,))
> 1: GlobalRef
> mod: Module Memoization
> name: Symbol Tuple
> binding: Core.Binding
> value: #undef
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding
> value: Tuple <: Any
> globalref: GlobalRef
> mod: Module Core
> name: Symbol Tuple
> binding: Core.Binding#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: Any
> flags: UInt8 0x03
> ty: #undef
> flags: UInt8 0x00
> 2: GlobalRef
> mod: Module Memoization
> name: Symbol Any
> binding: Core.Binding
> value: #undef
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding
> value: Any
> globalref: GlobalRef
> mod: Module Core
> name: Symbol Any
> binding: Core.Binding#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: Any
> flags: UInt8 0x03
> ty: #undef
> flags: UInt8 0x00
> 2: Expr
> head: Symbol block
> args: Array{Any}((2,))
> 1: LineNumberNode
> line: Int64 172
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 2: Expr
> head: Symbol call
> args: Array{Any}((3,))
> 1: GlobalRef
> mod: Module Core
> name: Symbol eval
> binding: Core.Binding
> value: eval (function of type typeof(Core.eval))
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: #undef
> flags: UInt8 0x03
> 2: Module Main
> 3: Expr
> head: Symbol call
> args: Array{Any}((5,))
> 1: GlobalRef
> mod: Module Core
> name: Symbol _expr
> binding: Core.Binding
> value: _expr (function of type typeof(Core._expr))
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: Any
> flags: UInt8 0x01
> 2: QuoteNode
> value: Symbol macrocall
> 3: QuoteNode
> value: Symbol @generated
> 4: QuoteNode
> value: LineNumberNode
> line: Int64 172
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 5: Expr
> head: Symbol call
> args: Array{Any}((4,))
> 1: GlobalRef
> mod: Module Core
> name: Symbol _expr
> binding: Core.Binding
> value: _expr (function of type typeof(Core._expr))
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: Any
> flags: UInt8 0x01
> 2: QuoteNode
> value: Symbol function
> 3: Expr
> head: Symbol call
> args: Array{Any}((4,))
> 1: GlobalRef
> mod: Module Core
> name: Symbol _expr
> binding: Core.Binding
> value: _expr (function of type typeof(Core._expr))
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: Any
> flags: UInt8 0x01
> 2: QuoteNode
> value: Symbol call
> 3: Expr
> head: Symbol copyast
> args: Array{Any}((1,))
> 1: QuoteNode
> value: Expr
> head: Symbol .
> args: Array{Any}((2,))
> 1: Module Memoization
> 2: QuoteNode
> value: Symbol _static_get_cache
> 4: Expr
> head: Symbol call
> args: Array{Any}((3,))
> 1: GlobalRef
> mod: Module Core
> name: Symbol _expr
> binding: Core.Binding
> value: _expr (function of type typeof(Core._expr))
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: Any
> flags: UInt8 0x01
> 2: QuoteNode
> value: Symbol ::
> 3: Expr
> head: Symbol call
> args: Array{Any}((4,))
> 1: GlobalRef
> mod: Module Core
> name: Symbol _expr
> binding: Core.Binding
> value: _expr (function of type typeof(Core._expr))
> globalref: GlobalRef#= circular reference @-2 =#
> owner: Core.Binding#= circular reference @-1 =#
> ty: Any
> flags: UInt8 0x01
> 2: QuoteNode
> value: Symbol call
> 3: QuoteNode
> value: Symbol typeof
> 4: Symbol #21#func
> 4: Expr
> head: Symbol copyast
> args: Array{Any}((1,))
> 1: QuoteNode
> value: Expr
> head: Symbol block
> args: Array{Any}((3,))
> 1: LineNumberNode
> line: Int64 172
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 2: LineNumberNode
> line: Int64 173
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 3: Expr
> head: Symbol call
> args: Array{Any}((1,))
> 1: UnionAll
> var: TypeVar
> name: Symbol K
> lb: Union{}
> ub: Any
> body: UnionAll
> var: TypeVar
> name: Symbol V
> lb: Union{}
> ub: Any
> body: IdDict{K, V} <: AbstractDict{K, V}
> ht::Vector{Any}
> count::Int64
> ndel::Int64
> 3: LineNumberNode
> line: Int64 180
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 4: Expr
> head: Symbol call
> args: Array{Any}((2,))
> 1: empty_cache! (function of type typeof(Memoization.empty_cache!))
> 2: Symbol f
> 7: LineNumberNode
> line: Int64 182
> file: Symbol /Users/cameron/.julia/packages/Memoization/7WxyR/src/Memoization.jl
> 8: Symbol #21#func
> 
> ```
