# Metaprogramming: macro creating types

**URL:** https://discourse.julialang.org/t/metaprogramming-macro-creating-types/87439
**Category:** General Usage
**Tags:** macros
**Created:** [September 18, 2022, 1:10pm UTC](https://discourse.julialang.org/t/metaprogramming-macro-creating-types/87439 "2022-09-18T13:10:01Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![davidavdav](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davidavdav/32/1065_2.png) [@davidavdav](https://discourse.julialang.org/u/davidavdav)
#### Post date: [September 18, 2022, 1:10pm UTC](https://discourse.julialang.org/t/metaprogramming-macro-creating-types/87439/1 "2022-09-18T13:10:01Z")

</div>

Hi,

I’ve been struggling with making a macro that will define a new wrapper type for me, with some minimal functions to make the wrapper type function more/less the same as the type it waps.

For now have the minimal wrapper for `Dict` (of which the interface specs seem to be missing from the [documentation](https://docs.julialang.org/en/v1/manual/interfaces/#Interfaces)):

```julia
macro WrapsDict(MyDict)
    return quote
        ## type
        struct $MyDict{K,V} <: AbstractDict{K,V} 
            d::Dict{K,V}
        end
        ## constructor
        $MyDict(itr...) = $MyDict(Dict(itr...))
        ## minimal methods
        Base.iterate(d::$MyDict, state...) = iterate(d.d, state...)
        Base.length(d::$MyDict) = length(d.d)
        Base.get(d::$MyDict, k, v) = get(d.d, k, v)
    end
end

```

When I run this code, as `@WrapsDict(Dictionary)`, the type construction and constructor definitions work, but in the definition of the methods, it seems that the newly defined type is unknown at that moment:

```julia
ERROR: ArgumentError: invalid type for argument d in method definition for iterate 

```

I suspect that this is a scope or hygiene problem that I can’t wrap my head around.

A concrete instantiation of the code above, without the macro and with `Dictionary` replacing `$MyDict`, does everything as expected.

Any ideas if this can be solved? Thanks!

---

<div class="post-metadata">

### Author: ![dylanxyz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dylanxyz/32/36646_2.png) [@dylanxyz](https://discourse.julialang.org/u/dylanxyz)
#### Post date: [September 18, 2022, 1:35pm UTC](https://discourse.julialang.org/t/metaprogramming-macro-creating-types/87439/2 "2022-09-18T13:35:17Z")

</div>

You need to [**escape**](https://docs.julialang.org/en/v1/base/base/#Base.esc) `MyDict`:

```julia
julia> macro WrapsDict(MyDict)
    MyDict = esc(MyDict)
    return quote
        ## type
        struct $MyDict{K,V} <: AbstractDict{K,V} 
            d::Dict{K,V}
        end
        ## constructor
        $MyDict(itr...) = $MyDict(Dict(itr...))
        ## minimal methods
        Base.iterate(d::$MyDict, state...) = iterate(d.d, state...)
        Base.length(d::$MyDict) = length(d.d)
        Base.get(d::$MyDict, k, v) = get(d.d, k, v)
    end
end
@WrapsDict (macro with 1 method)

julia> @WrapsDict(Foo)

julia> Foo((:a => 1, :b => 2))
Foo{Symbol, Int64} with 2 entries:
  :a => 1
  :b => 2

```

---

<div class="post-metadata">

### Author: ![davidavdav](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davidavdav/32/1065_2.png) [@davidavdav](https://discourse.julialang.org/u/davidavdav)
#### Post date: [September 19, 2022, 8:52am UTC](https://discourse.julialang.org/t/metaprogramming-macro-creating-types/87439/3 "2022-09-19T08:52:12Z")

</div>

Thanks! I tried escaping `$MyDict` in various sub-expressions, but to no avail. I couldn’t have imagined the solution would be so simple.
