8.7 Modules and Macros
Rhombus’s module system cooperates closely with Rhombus’s macro system
(see Expression Macros and Definition and Declaration Macros). For example, in
the same way that the rhombus module provides syntax
for import and fun, importing other modules can
introduce new macro-based syntactic forms—
Macros that are defined within a module work the right way when they are imported into another module. Here’s a module that defines and exports noisy_fun, but it does not export the show_arguments function:
noisy_fun
$body
...'
fun show_arguments(name, args):
The noisy_fun form is like fun for a function definition, but it causes each call to the function to print the arguments that are provided to the function. After importing the noisy module, an example of using noisy_fun to define a function looks like this:
noisy_fun f(x, y):
x + y
f(1, 2) // prints "calling f with arguments [1, 2]"
Roughly, the def_noisy form works by replacing
noisy_fun f(x, y):
x + y
with
fun f(x, y):
show_arguments(#'f, [x, y])
x + y
Since show_arguments isn’t exported by the
noisy module, however, this literal textual
replacement is not quite right. The actual replacement correctly
tracks the origin of identifiers like show_arguments, so
they can refer to other definitions in the place where the macro is
defined—
There’s more to the macro and module interaction than identifier binding. The defn.macro form is itself a macro, and it expands to compile-time code that implements the transformation from noisy_fun into fun. The module system keeps track of which code needs to run at compile time and which needs to run normally.