]> gitweb.factorcode.org Git - factor.git/blob - basis/macros/macros-docs.factor
Factor source files should not be executable
[factor.git] / basis / macros / macros-docs.factor
1 USING: help.markup help.syntax quotations kernel
2 stack-checker.transforms sequences ;
3 IN: macros
4
5 HELP: MACRO:
6 { $syntax "MACRO: word ( inputs... -- ) definition... ;" }
7 { $description "Defines a code transformation. The definition must have stack effect " { $snippet "( inputs... -- quot )" } "." }
8 { $notes
9   "A call of a macro inside a word definition is replaced with the quotation expansion at compile-time if precisely the following conditions hold:"
10   { $list
11     { "All inputs to the macro call are literal" }
12     { "The word calling the macro has a static stack effect" }
13     { "The expansion quotation produced by the macro has a static stack effect" }
14   }
15   "If any of these conditions fail to hold, the macro will still work, but expansion will be performed at run-time."
16   $nl
17   "Other than possible compile-time expansion, the following two definition styles are equivalent:"
18     { $code "MACRO: foo ... ;" }
19     { $code ": foo ... call ;" }
20   "Conceptually, macros allow computation to be moved from run-time to compile-time, splicing the result of this computation into the generated quotation."
21 }
22 { $examples
23   "A macro that calls a quotation but preserves any values it consumes off the stack:"
24   { $code
25     "USING: fry generalizations ;" 
26     "MACRO: preserving ( quot -- )"
27     "    [ infer in>> length ] keep '[ _ ndup @ ] ;"
28   }
29   "Using this macro, we can define a variant of " { $link if } " which takes a predicate quotation instead of a boolean; any values consumed by the predicate quotation are restored immediately after:"
30   { $code
31     ": ifte ( pred true false -- ) [ preserving ] 2dip if ; inline"
32   }
33   "Note that " { $snippet "ifte" } " is an ordinary word, and it passes one of its inputs to the macro. If another word calls " { $snippet "ifte" } " with all three input quotations literal, then " { $snippet "ifte" } " will be inlined and " { $snippet "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."
34   $nl
35   "The " { $snippet "ifte" } " combinator presented here has similar semantics to the " { $snippet "ifte" } " combinator of the Joy programming language."
36 } ;
37
38 HELP: macro
39 { $class-description "Class of words defined with " { $link POSTPONE: MACRO: } "." } ;
40
41 ARTICLE: "macros" "Macros"
42 "The " { $vocab-link "macros" } " vocabulary implements " { $emphasis "macros" } ", which are code transformations that may run at compile-time under the right circumstances."
43 $nl
44 "Macros can be used to give static stack effects to combinators that otherwise would not have static stack effects. Macros can be used to calculate lookup tables and generate code at compile time, which can improve performance, the level of abstraction and simplify code."
45 $nl
46 "Factor macros are similar to Lisp macros; they are not like C preprocessor macros."
47 $nl
48 "Defining new macros:"
49 { $subsections POSTPONE: MACRO: }
50 "A slightly lower-level facility, " { $emphasis "compiler transforms" } ", allows an ordinary word definition to co-exist with a version that performs compile-time expansion."
51 { $subsections define-transform }
52 "An example is the " { $link member? } " word. If the input sequence is a literal, the compile transform kicks in and converts the " { $link member? } " call into a series of conditionals. Otherwise, if the input sequence is not literal, a call to the definition of " { $link member? } " is generated."
53 { $see-also "generalizations" "fry" } ;
54
55 ABOUT: "macros"