]> gitweb.factorcode.org Git - factor.git/commitdiff
Improving macro docs
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Fri, 6 Feb 2009 16:22:09 +0000 (10:22 -0600)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Fri, 6 Feb 2009 16:22:09 +0000 (10:22 -0600)
basis/macros/macros-docs.factor
basis/macros/macros.factor
core/kernel/kernel-docs.factor

index 704cae459a268683ab32063b00a1ea5c6010044b..acd2c3383f2e6ca7ba5a552f7773272fa3d4ebfb 100644 (file)
@@ -1,27 +1,54 @@
-USING: help.markup help.syntax quotations kernel ;
+USING: help.markup help.syntax quotations kernel
+stack-checker.transforms sequences ;
 IN: macros
 
 HELP: MACRO:
 { $syntax "MACRO: word ( inputs... -- ) definition... ;" }
-{ $description "Defines a compile-time code transformation. If all inputs to the word are literal and the word calling the macro has a static stack effect, then the macro body is invoked at compile-time to produce a quotation; this quotation is then spliced into the compiled code. If the inputs are not literal, or if the word is invoked from a word which does not have a static stack effect, the macro body will execute every time and the result will be passed to " { $link call } "."
-$nl
-"The stack effect declaration must be present because it tells the compiler how many literal inputs to expect."
-}
+{ $description "Defines a code transformation. The definition must have stack effect " { $snippet "( inputs... -- quot )" } "." }
 { $notes
-    "Semantically, the following two definitions are equivalent:"
+  "A call of a macro inside a word definition is replaced with the quotation expansion at compile-time if precisely the following conditions hold:"
+  { $list
+    { "All inputs to the macro call are literal" }
+    { "The word calling the macro has a static stack effect" }
+    { "The expansion quotation produced by the macro has a static stack effect" }
+  }
+  "If any of these conditions fail to hold, the macro will still work, but expansion will be performed at run-time."
+  $nl
+  "Other than possible compile-time expansion, the following two definition styles are equivalent:"
     { $code "MACRO: foo ... ;" }
     { $code ": foo ... call ;" }
-    "However, the compiler folds in macro definitions at compile-time where possible; if the macro body performs an expensive calculation, it can lead to a performance boost."
+  "Conceptually, macros allow computation to be moved from run-time to compile-time, splicing the result of this computation into the generated quotation."
+}
+{ $examples
+  "A macro that calls a quotation but preserves any values it consumes off the stack:"
+  { $code
+    "USING: fry generalizations ;" 
+    "MACRO: preserving ( quot -- )"
+    "    [ infer in>> length ] keep '[ _ ndup @ ] ;"
+  }
+  "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:"
+  { $code
+    ": ifte ( pred true false -- ) [ preserving ] 2dip if ; inline"
+  }
+  "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."
+  $nl
+  "The " { $snippet "ifte" } " combinator presented here has similar semantics to the " { $snippet "ifte" } " combinator of the Joy programming language."
 } ;
 
 HELP: macro
 { $class-description "Class of words defined with " { $link POSTPONE: MACRO: } "." } ;
 
 ARTICLE: "macros" "Macros"
-"The " { $vocab-link "macros" } " vocabulary implements macros in the Lisp sense; compile-time code transformers and generators. 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."
+"The " { $vocab-link "macros" } " vocabulary implements " { $emphasis "macros" } ", which are code transformations that may run at compile-time under the right circumstances."
+$nl
+"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."
+$nl
+"Factor macros are similar to Lisp macros; they are not like C preprocessor macros."
 $nl
 "Defining new macros:"
 { $subsection POSTPONE: MACRO: }
-"Macros are really just a very thin layer of syntax sugar over " { $link "compiler-transforms" } "." ;
+"A slightly lower-level facility, " { $emphasis "compiler transforms" } ", allows an ordinary word definition to co-exist with a version that performs compile-time expansion."
+{ $subsection define-transform }
+"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." ;
 
 ABOUT: "macros"
index 1481e6eea57d832bc177a0207e26e156d1c5feb7..4fba7efba3890be862ea629c0acc5f97e78f18cf 100644 (file)
@@ -4,9 +4,13 @@ USING: parser kernel sequences words effects combinators assocs
 definitions quotations namespaces memoize accessors ;
 IN: macros
 
+<PRIVATE
+
 : real-macro-effect ( word -- effect' )
     "declared-effect" word-prop in>> 1 <effect> ;
 
+PRIVATE>
+
 : define-macro ( word definition -- )
     [ "macro" set-word-prop ]
     [ over real-macro-effect memoize-quot [ call ] append define ]
index d85a51edffa272c769ae912d6fb4bbe3c4ba321d..71183093ee14357e037099ce494c8fc0cabb123e 100644 (file)
@@ -949,6 +949,13 @@ ARTICLE: "assertions" "Assertions"
 { $subsection assert }
 { $subsection assert= } ;
 
+ARTICLE: "dataflow-combinators" "Data flow combinators"
+"Data flow combinators pass values between quotations:"
+{ $subsection "slip-keep-combinators" }
+{ $subsection "cleave-combinators" }
+{ $subsection "spread-combinators" }
+{ $subsection "apply-combinators" } ;
+
 ARTICLE: "dataflow" "Data and control flow"
 { $subsection "evaluator" }
 { $subsection "words" }
@@ -956,16 +963,9 @@ ARTICLE: "dataflow" "Data and control flow"
 { $subsection "booleans" }
 { $subsection "shuffle-words" }
 "A central concept in Factor is that of a " { $emphasis "combinator" } ", which is a word taking code as input."
-$nl
-"Data flow combinators:"
-{ $subsection "slip-keep-combinators" }
-{ $subsection "cleave-combinators" }
-{ $subsection "spread-combinators" }
-{ $subsection "apply-combinators" }
-"Control flow combinators:"
+{ $subsection "dataflow-combinators" }
 { $subsection "conditionals" }
 { $subsection "looping-combinators" }
-"Additional combinators:"
 { $subsection "compositional-combinators" }
 { $subsection "combinators" }
 "More combinators are defined for working on data structures, such as " { $link "sequences-combinators" } " and " { $link "assocs-combinators" } "."
@@ -973,6 +973,7 @@ $nl
 "Advanced topics:"
 { $subsection "assertions" }
 { $subsection "implementing-combinators" }
+{ $subsection "macros" }
 { $subsection "errors" }
 { $subsection "continuations" } ;