# How to define a macro via Package Extension?

**URL:** <https://discourse.julialang.org/t/how-to-define-a-macro-via-package-extension/114218>\
**Category:** General Usage\
**Tags:** question\
**Created:** [May 14, 2024, 6:01am UTC](https://discourse.julialang.org/t/how-to-define-a-macro-via-package-extension/114218 "2024-05-14T06:01:19Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [May 14, 2024, 6:01am UTC](https://discourse.julialang.org/t/how-to-define-a-macro-via-package-extension/114218/1 "2024-05-14T06:01:19Z")

</div>

I thought that you’d define functions my extending the original package’s functions like `MyPackage.myfunc(::SpecialExtensionType) = ...`

The same however does not work for macros

```julia
macro MyPackage.mymacro()
end

```

throws error `ERROR: syntax: invalid macro definition ...`

---

<div class="post-metadata">

**Author:** ![disberd](https://avatars.discourse-cdn.com/v4/letter/d/8edcca/32.png) [@disberd](https://discourse.julialang.org/u/disberd)\
**Post date:** [May 14, 2024, 6:32am UTC](https://discourse.julialang.org/t/how-to-define-a-macro-via-package-extension/114218/2 "2024-05-14T06:32:02Z")

</div>

What if your macro definition in the main package just calls a function that returns the corresponding expression, and then you just create a method for that function in the extension?

Many macro definitions already internally just call a function for generating the expression

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [May 14, 2024, 7:46am UTC](https://discourse.julialang.org/t/how-to-define-a-macro-via-package-extension/114218/3 "2024-05-14T07:46:42Z")

</div>

I feel hesitant to do so because then I need to decide “ahead” on the arguments, and cannot use dispatch here.

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [May 14, 2024, 7:47am UTC](https://discourse.julialang.org/t/how-to-define-a-macro-via-package-extension/114218/4 "2024-05-14T07:47:15Z")

</div>

I actually found that you can extend macros by importing them.  
`import MyPackage: @mymacro`  
you then can extend the method table of the macro by defining simply

```julia
macro mymacro(#= ... =#)
    # ...
end

```

---

<div class="post-metadata">

**Author:** ![disberd](https://avatars.discourse-cdn.com/v4/letter/d/8edcca/32.png) [@disberd](https://discourse.julialang.org/u/disberd)\
**Post date:** [May 14, 2024, 7:57am UTC](https://discourse.julialang.org/t/how-to-define-a-macro-via-package-extension/114218/5 "2024-05-14T07:57:37Z")

</div>

Nice, you could also do something a bit more ugly without directly importing but your solution does look cleaner:

```julia-repl
julia> module TESTT
       macro asd end
       end

julia> import .TESTT

julia> TESTT.var"@asd"( __source__ ::LineNumberNode, __module__ ::Module, x) = 15

julia> TESTT.@asd 0
15

```

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [May 14, 2024, 7:11pm UTC](https://discourse.julialang.org/t/how-to-define-a-macro-via-package-extension/114218/6 "2024-05-14T19:11:56Z")

</div>

Why _isn’t_ this allowed though? I thought it’d be an issue somewhere but couldn’t find one, just these barely related ones

[Macro Inconsistency using Module Qualification · Issue #32301 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/32301)

[macro qualification inconsistency · Issue #1769 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/1769)

---

<div class="post-metadata">

**Author:** ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)\
**Post date:** [May 15, 2024, 3:11am UTC](https://discourse.julialang.org/t/how-to-define-a-macro-via-package-extension/114218/7 "2024-05-15T03:11:22Z")

</div>

> [@schlichtanders](#):
>
> ``  
> you then can extend the method table of the macro by defining simply
> 
> ```julia
> macro mymacro(#= ... =#)
> # ...
> end
> 
> ```

It’s worth noting that for the definition that needs to be in the base package itself, much like you can do

```julia
function foo end

```

you can do

```julia
macro foo end

```

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [May 16, 2024, 9:02am UTC](https://discourse.julialang.org/t/how-to-define-a-macro-via-package-extension/114218/8 "2024-05-16T09:02:09Z")

</div>

wooooo!! I always thought that it would make sense to treat macros as functions with extra arguments, but never thought that it is already the case!

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [May 16, 2024, 9:07am UTC](https://discourse.julialang.org/t/how-to-define-a-macro-via-package-extension/114218/9 "2024-05-16T09:07:42Z")

</div>

I am also surprised. Looks like an inconsistency for me.

Thanks for the research. I created a new issue now

> <https://github.com/JuliaLang/julia/issues/54488>
>
> As a outcome from this discourse issue https://discourse.julialang.org/t/how-to-…define-a-macro-via-package-extension/114218/5
> I want to open an issue to track that the syntax to extend functions and macros do not match.
> 
> While extending functions and macros works the same when importing them (like \`import OtherPackage: @theirmacro\`), using qualified definitions only works for functions.
> 
> works:
> \`\`\`julia
> function OtherPackage.theirfunction(args...)
> # works
> end
> \`\`\`
> doesn't work:
> \`\`\`julia
> macro OtherPackage.theirmacro(args...)
> # fails with \`ERROR: syntax: invalid macro definition ...\`
> end
> \`\`\`
> 
> As the functionality of extending is already support for both, it would be great if also the syntax support is consistent.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [May 19, 2024, 7:49pm UTC](https://discourse.julialang.org/t/how-to-define-a-macro-via-package-extension/114218/10 "2024-05-19T19:49:29Z")

</div>

> [@Benny](#):
>
> Why _isn’t_ this allowed though?

If I have to guess, it’s because macros couldn’t be extended at all until late in the pre-v1 development: for a long time there could be a single method for macros, so extending them made little sense, let alone in a different module.
