In Lisp Flavored Erlang (LFE), macros are powerful tools for metaprogramming, allowing developers to define new language constructs and perform code transformations at compile time. LFE macros are based on the macro system inherited from Lisp, which provides a mechanism for manipulating code as data.
Some key points about LFE macros:
Code as Data: Macros operate on code as data, which means you can manipulate and transform LFE code programmatically during compilation.
Compile Time Evaluation: Macros are expanded at compile time, not runtime. This means that macro expansions are part of the compilation process and do not incur any runtime overhead.
Hygiene: LFE macros support hygiene, which helps prevent unintended variable capture and maintain separation between macro and surrounding code.
Power and Flexibility: LFE macros provide a powerful mechanism for extending the language with new features and abstractions. They can be used to define control structures, domain-specific languages (DSLs), and various other code transformations.
Macros are usually defined with the defmacro form.
(defmacro lfecon (test body)
(list 'if (list 'not test) body))
Here a macro lfecon which returns an expression which evaluates the body if the test is false:
(lfecon (> 33 44) 'yes)
To test a macro and look at its expansion we can use the function macroexpand which takes a macro call and generates its expansion.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.
(macroexpand '(lfecon (> 33 43) 'yes) $ENV)
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.