How to define a macro via Package Extension?

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

macro MyPackage.mymacro()
end

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

1 Like

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

3 Likes

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

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

macro mymacro(#= ... =#)
    # ...
end
2 Likes

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

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
1 Like

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

macro qualification inconsistency · Issue #1769 · JuliaLang/julia · GitHub

1 Like

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

function foo end

you can do

macro foo end
1 Like

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!

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

Thanks for the research. I created a new issue now

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.

1 Like