Macros
Macros are a very powerful concept in Julia and we will use them throughout the next sessions. The main idea of macros is to allow the generation of code in the final body of a program. At its basis, a macro is similar to a function, as it maps a tuple of arguments to a returned expression. Therefore, in order to distinguish macros in the code, Julia reserves the @
symbol as the first character for macro definitions. Apart from that convention, there are two major differences between macros and functions. A macro:
is compiled directly and not at the first call,
is executed when the code is parsed.
The second feature is the important one, as we can manipulate the code at runtime. The nice thing about macros is, we can insert quite powerful code by still keeping the readability high. Later on we will see how this works, but let us keep it simple to begin with.
An easy example from the Julia documentation on macros is:
julia> macro sayhello(name)
return :( println("Hello, ", $name) )
end
@sayhello (macro with 1 method)
julia> @sayhello("student n")
Hello, student n
julia> @sayhello "student n+1"
Hello, student n+1
One thing to note here is, that in the REPL the macro is executed immediately and we see the result right away.
It would not be Julia if there was not a macro that can be used to view what a macro is actually doing with an argument. This is the @macroexpand
macro:
julia> @macroexpand @sayhello "Student n+1"
:(Main.println("Hello, ", "Student n+1"))
Of course we can also use the other features of Julia with macros, like multiple dispatch, which is something for the exercise.
Write a macro
m
with different invocations for one argument and for two arguments (just printx arguments
as return value).Add a version where the input is an integer and test with
@m 1
What happens when you run the code
x = 1
@m x
julia> macro m(x)
return :( println("One arguments") )
end
@m (macro with 1 method)
julia> macro m(x, y)
return :( println("Two arguments") )
end
@m (macro with 2 methods)
julia> macro m(::Int)
return :( println("An Integer") )
end
@m (macro with 3 methods)
julia> @m 1
An Integer
julia> @m x y
Two arguments
julia> x = 1
1
julia> @m x
One arguments