Factor handbook » The language » Macros

Next:define-transform ( word quot n -- )


MACRO: word ( inputs... -- quot ) definition... ;

Word description
Defines a macro word. The definition must have stack effect ( inputs... -- quot ).

A call of a macro inside a word definition is replaced with the quotation expansion at compile-time. The following two conditions must hold:
All inputs to the macro call must be literals
The expansion quotation produced by the macro has a static stack effect

Macros allow computation to be moved from run-time to compile-time, splicing the result of this computation into the generated quotation.

A macro that calls a quotation but preserves any values it consumes off the stack:
USING: fry generalizations kernel macros stack-checker ; MACRO: preserving ( quot -- quot' ) [ inputs ] keep '[ _ ndup @ ] ;

Using this macro, we can define a variant of if which takes a predicate quotation instead of a boolean; any values consumed by the predicate quotation are restored immediately after:
: ifte ( pred true false -- ) [ preserving ] 2dip if ; inline

Note that ifte is an ordinary word, and it passes one of its inputs to the macro. If another word calls ifte with all three input quotations literal, then ifte will be inlined and preserving will expand at compile-time, and the generated machine code will be exactly the same as if the inputs consumed by the predicate were duplicated by hand.

The ifte combinator presented here has similar semantics to the ifte combinator of the Joy programming language.

See also