The most common way to write programs in LFE that write programs is by defining macros. Macros work by transformation. When you define a macro you say how a call to it should be translated, the macro expansion, which is then done automatically by the compile. The code generated by the macro then becomes an integral part of the program.

Macros are usually defined with the defmacro form. It resembles a defun but instead of defining the value a call returns it defines how the call should be expanded. For example a macro unless which returns an expression which evaluates the body if the test is false:

(defmacro unless (test body)
  (list 'if (list 'not test) body))

So if we type into the top-level REPL:

lfe> (unless (> 3 4) 'yes)
lfe> (unless (is_number 'foo) 'number)

To test a macro and look at its expansion we can use the function macroexpand which takes a macro call and generates its expansion1:

lfe> (macroexpand '(unless (> 3 4) 'yes) $ENV)
(if (not (> 3 4)) 'yes)

If a macro call expands into another macro call then the compiler or the top-level REPL it will keep expanding until the expansion is no longer a macro. It is the expansion of the macro call which is then inserted into the code. So in the example of unless it is the resultant if form which is then inserted into the code.


1 The extra argument $ENV is needed as this is where the REPL keeps its locally defined functions and macros and we need to tell macroexpand where to look.