Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I retrieve the methods of a Julia macro?

In Julia, the methods function may be used to retrieve the methods of a function.

julia> f(::Int) = 0
f (generic function with 1 method)

julia> f(::String) = ""
f (generic function with 2 methods)

julia> methods(f)
# 2 methods for generic function "f":
f(::String) in Main at REPL[1]:1
f(::Int64) in Main at REPL[0]:1

Macros can also have multiple methods.

julia> macro g(::Int)
           0
       end
@g (macro with 1 method)

julia> macro g(::String)
           ""
       end
@g (macro with 2 methods)

julia> @g 123
0

julia> @g "abc"
""

However, the methods function does not seem to work on macros because Julia first calls the macro, due to the fact that they do not need parentheses.

julia> methods(@g)
ERROR: MethodError: no method matching @g()
Closest candidates are:
  @g(::String) at REPL[2]:2
  @g(::Int64) at REPL[1]:2

I tried using an Expression to contain the macro, but this did not work.

julia> methods(:@g)
# 0 methods for generic function "(::Expr)":

How can I retrieve the methods of a macro?

like image 560
Harrison Grodin Avatar asked Mar 27 '17 05:03

Harrison Grodin


People also ask

Does Julia have methods?

Julia allows the dispatch process to choose which of a function's methods to call based on the number of arguments given, and on the types of all of the function's arguments.

Why use macros Julia?

Macros are an incredibly useful feature in the Julia programming language. Not only can they be used as a “ shortcut” to calling methods, but they can also be used to turn regular code into expressions automatically.

What is a macro Julia?

Macros change existing source code or generate entirely new code. They are not some kind of more powerful function that unlocks secret abilities of Julia, they are just a way to automatically write code that you could have written out by hand anyway.


1 Answers

I would put a generic macro (@methods) inside a module (MethodsMacro) in my ~/.juliarc.jl along with the line: using MethodsMacro. This way you'd have it available at every Julia session, something like:

julia> module MethodsMacro                                               

       export @methods                                              

       macro methods(arg::Expr)                                     
           arg.head == :macrocall || error("expected macro name")   
           name = arg.args[] |> Meta.quot                           
           :(methods(eval($name)))                                  
       end                                                          

       macro methods(arg::Symbol)                                   
           :(methods($arg)) |> esc                                  
       end                                                          

       end                                                          
MethodsMacro                                                             

julia> using MethodsMacro                                                

julia> @methods @methods                                            
# 2 methods for macro "@methods":                                   
@methods(arg::Symbol) at REPL[48]:12                                
@methods(arg::Expr) at REPL[48]:6                                   

julia> f() = :foo; f(x) = :bar                                      
f (generic function with 2 methods)                                 

julia> @methods f                                                   
# 2 methods for generic function "f":                               
f() at REPL[51]:1                                                   
f(x) at REPL[51]:1     
like image 105
HarmonicaMuse Avatar answered Sep 29 '22 07:09

HarmonicaMuse