# 1 Macro Facility

A new macro facility has now been integrated into the Mozart system. This is not a preprocessing facility: preprocessors such as CPP or M4 are widely available and can be used for preprocessing arbitrary files. You could easily use them to preprocess files of Oz code. This is not what we discuss here. The Mozart macro facility is closer in spirit to that of Lisp.

## 1.4 Compiling functors that use macros

It doesn't work to write a functor that both defines macros and uses them: when the functor is being compiled the macros have not yet been defined. The trick is to take advantage of compiler options `--include` or `--environment` to get the compiler to execute code defining your macros before going on to compile your functor. We now describe how to achieve the desired effect using option `--environment`.

First we create a functor that defines new macros. It exports nothing, but just registers the macros. Suppose we write file `unless.oz` containing:

> `functor
> import Macro
> define
> fun {UnlessExpander fMacro(M|B|L C) Env}
> fBoolCase(
> B
> fSkip(unit)
> {Macro.listToSequence L}
> C)
> end
> {Macro.defmacro unless UnlessExpander}
> end`

We compile it as usual:

> `ozc -c unless.oz`

Now we write file `do.oz` that makes use of this macro:

> `functor
> import System(show:Show)
> export Do
> define
> proc {Do X Y}
> <<unless X<Y {Show X} {Show Y}>>
> end
> end`

The trick is to compile it as follows:

> `ozc -l 'Bogus=unless.ozf' -c do.oz`

When the compiler processes option `-l` it links in the new module `Bogus` using functor `unless.ozf`. Module `Bogus` is in itself uninteresting; only the side-effects resulting from linking it are really what we are after, namely to define and register new macros.