How to use macros for testing in Julia

In Julia's ecosystem, expressions and macros foster the metaprogramming paradigm. The macro concept can be considered a function for creating and evaluating expressions. Macros can be used to transform programs in a customized manner.

With macros, we can insert custom code during parsing and then execute that code during program execution.

Defining a macro

To define a macro, we need to use the keyword macro as shown below:

macro name(args) Unevaluated Input Expression –> Output Expression
Syntax

The args represents the input expression arguments which can take the form of symbols, other expressions, or literals.We can explore these arguments by calling the show() function within the body of the macro. The Unevaluated Input Expression is an expression in an unevaluated form, and the Output Expression is the resulting compiled expression.

Invoking a macro

Below is the syntax to invoke a macro:

@name(args) or @name args
Syntax

When debugging, we often want to know what expression the macro is evaluating without executing it. The following macroexpand method is used:

@macroexpand @name(args) or @macroexpand @name args

Let's take a look at the macros functioning below.

Code example 1

This basic example illustrates how to define and call a macro:

macro macro1(p1)
show(p1)
return :( println("\nMy macro input parameter is:" , $p1) )
end
@macro1("123")

Code explanation

Let's go through the code widget above:

  • Line 1: We define a macro named macro1 that takes one argument called p1.

  • Line 2: We display the value of the specified argument p1.

  • Line 3: We refer to the expression to be evaluated and returned by the macro.

  • Line 5: We invoke the macro1 macro previously declared.

Code example 2

The example below shows how a macro can be expanded to evaluate an expression specified as a parameter for testing purposes. Basically, It accepts an expression as a parameter and tests whether it is valid or not.

macro verify(ex)
print("\nVerifiying Expression ")
show(ex)
return :( $ex ? nothing : throw(AssertionError($(string(ex)))) )
end
try
@verify 1*1 == 1
print("\nExpression is valid ")
catch e
println("\n",e)
end
try
@verify 1+3 == 3
print("\nExpression is valid ")
catch e
println("\n",e)
end
try
@verify 2*1 == 1
print("\nExpression is valid ")
catch e
println("\n",e)
end

Code explanation

Let's go over the code widget above:

  • Line 1: We define a macro named verify that accepts one argument called ex.

  • Line 2: We print out an informative message.

  • Line 3: We display the value of the specified argument ex.

  • Line 4: We evaluate the expression ex provided as an argument, if true, then do nothing otherwise, throw an error.

  • Lines 7–12: We invoke the verify macro while specifying the expression 1*1 = 1 as an argument to test whether this expression is valid or not.

  • Lines 14–19: We invoke the verify macro while specifying the expression 1 + 3 == 3 as an argument to check whether this expression is valid or not.

  • Lines 21–26: We call the verify macro while specifying the expression 2*1 == 1 as an argument to ascertain the validity of this expression.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved