# Macro-defined callable structs \`ArgumentError: invalid type for argument number 1 in method definition\`

**URL:** <https://discourse.julialang.org/t/macro-defined-callable-structs-argumenterror-invalid-type-for-argument-number-1-in-method-definition/129971>\
**Category:** General Usage\
**Tags:** question, macros\
**Created:** [June 17, 2025, 3:46pm UTC](https://discourse.julialang.org/t/macro-defined-callable-structs-argumenterror-invalid-type-for-argument-number-1-in-method-definition/129971 "2025-06-17T15:46:32Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![user664303](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/user664303/32/37843_2.png) [@user664303](https://discourse.julialang.org/u/user664303)\
**Post date:** [June 17, 2025, 3:46pm UTC](https://discourse.julialang.org/t/macro-defined-callable-structs-argumenterror-invalid-type-for-argument-number-1-in-method-definition/129971/1 "2025-06-17T15:46:32Z")

</div>

Running

```julia
macro definestruct(name, ndims)
    return quote
        struct $name{T}
            v::Vector{T}
        end
        $name(v::Vector{T}) where T = $name{T}(v)
        nvars(::$name) = $ndims
    end
end
@definestruct(MyStruct, 6)

```

produces the following error:

> ERROR: ArgumentError: invalid type for argument number 1 in method definition for #39#nvars at /Users/olly/.julia/dev/scratch/macro.jl:7

If I comment out the line above the `nvars` definition, it goes away. I don’t really understand why the error is happening. Can anyone explain?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [June 17, 2025, 3:51pm UTC](https://discourse.julialang.org/t/macro-defined-callable-structs-argumenterror-invalid-type-for-argument-number-1-in-method-definition/129971/2 "2025-06-17T15:51:17Z")

</div>

```julia
julia> @macroexpand @definestruct(MyStruct, 6)
quote
    #= REPL[1]:3 =#
    struct MyStruct{var"#13#T"}
        #= REPL[1]:4 =#
        v::Main.Vector{var"#13#T"}
    end
    #= REPL[1]:6 =#
    (var"#11#MyStruct"(var"#14#v"::Main.Vector{var"#15#T"}) where var"#15#T") = begin
            #= REPL[1]:6 =#
            var"#11#MyStruct"{var"#15#T"}(var"#14#v")
        end
    #= REPL[1]:7 =#
    var"#12#nvars"(::var"#11#MyStruct") = begin
            #= REPL[1]:7 =#
            6
        end
end

```

as you can see, the `(var"#11#MyStruct"(var"#14#v"::Main.Vector{var"#15#T"}) where var"#15#T")` does not define something on the `MyStruct`.

I think you want to escape this:

```julia
julia> macro definestruct(name, ndims)
           return esc(quote
               struct $name{T}
                   v::Vector{T}
               end
               $name(v::Vector{T}) where T = $name{T}(v)
               nvars(::$name) = $ndims
           end)
       end
@definestruct (macro with 1 method)

julia> @macroexpand @definestruct(MyStruct, 6)
quote
    #= REPL[4]:3 =#
    struct MyStruct{T}
        #= REPL[4]:4 =#
        v::Vector{T}
    end
    #= REPL[4]:6 =#
    (MyStruct(v::Vector{T}) where T) = begin
            #= REPL[4]:6 =#
            MyStruct{T}(v)
        end
    #= REPL[4]:7 =#
    nvars(::MyStruct) = begin
            #= REPL[4]:7 =#
            6
        end
end

```

---

<div class="post-metadata">

**Author:** ![user664303](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/user664303/32/37843_2.png) [@user664303](https://discourse.julialang.org/u/user664303)\
**Post date:** [June 17, 2025, 5:36pm UTC](https://discourse.julialang.org/t/macro-defined-callable-structs-argumenterror-invalid-type-for-argument-number-1-in-method-definition/129971/3 "2025-06-17T17:36:58Z")

</div>

Thank you so much. Is there a simple explanation for what the parser was doing, and why escaping was the solution? Is it an issue of scope?

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [June 17, 2025, 6:07pm UTC](https://discourse.julialang.org/t/macro-defined-callable-structs-argumenterror-invalid-type-for-argument-number-1-in-method-definition/129971/4 "2025-06-17T18:07:39Z")

</div>

This is the standard behavior when you write a macro. The key concept is _macro hygiene_. The manual does a decent job at explaining it:

> **[Metaprogramming · The Julia Language](https://docs.julialang.org/en/v1/manual/metaprogramming/#Hygiene)**
>
> Documentation for The Julia Language.
