finish macro docs
authorAndy Wingo <wingo@pobox.com>
Fri, 19 Mar 2010 12:16:57 +0000 (13:16 +0100)
committerAndy Wingo <wingo@pobox.com>
Fri, 19 Mar 2010 12:16:57 +0000 (13:16 +0100)
* doc/ref/api-macros.texi: Finish macro docs.

doc/ref/api-macros.texi

index e8936e4..51f54ed 100644 (file)
@@ -734,31 +734,125 @@ them.
 @node Identifier Macros
 @subsection Identifier Macros
 
+When the syntax expander sees a form in which the first element is a macro, the
+whole form gets passed to the macro's syntax transformer. One may visualize this
+as:
+
+@example
+(define-syntax foo foo-transformer)
+(foo @var{arg}...)
+;; expands via
+(foo-transformer #'(foo @var{arg}...))
+@end example
+
+If, on the other hand, a macro is referenced in some other part of a form, the
+syntax transformer is invoked with only the macro reference, not the whole form.
+
+@example
+(define-syntax foo foo-transformer)
+foo
+;; expands via
+(foo-transformer #'foo)
+@end example
+
+This allows bare identifier references to be replaced programmatically via a
+macro. @code{syntax-rules} provides some syntax to effect this transformation
+more easily.
+
+@deffn {Syntax} identifier-syntax exp
+Returns a macro transformer that will replace occurences of the macro with
+@var{exp}.
+@end deffn
+
+For example, if you are importing external code written in terms of @code{fx+},
+the fixnum addition operator, but Guile doesn't have @code{fx+}, you may use the
+following to replace @code{fx+} with @code{+}:
+
+@example
+(define-syntax fx+ (identifier-syntax +))
+@end example
+
+Later versions of the @code{psyntax} @code{syntax-case} expander, on which
+Guile's syntax expander is based, include @code{identifier-syntax} support for
+recognizing identifiers on the left-hand side of a @code{set!} expression as
+well. Guile should port that code to its expander.
+
 @node Eval When
 @subsection Eval-when
 
-@node Internal Macros
-@subsection Internal Macros
+As @code{syntax-case} macros have the whole power of Scheme available to them,
+they present a problem regarding time: when a macro runs, what parts of the
+program are available for the macro to use?
 
+The default answer to this question is that when you import a module (via
+@code{define-module} or @code{use-modules}), that module will be loaded up at
+expansion-time, as well as at run-time. Additionally, top-level syntactic
+definitions within one compilation unit made by @code{define-syntax} are also
+evaluated at expansion time, in the order that they appear in the compilation
+unit (file).
+
+But if a syntactic definition needs to call out to a normal procedure at
+expansion-time, it might well need need special declarations to indicate that
+the procedure should be made available at expansion-time.
+
+For example, the following code will work at a REPL, but not in a file:
+
+@example
+;; incorrect
+(use-modules (srfi srfi-19))
+(define (date) (date->string (current-date)))
+(define-syntax %date (identifier-syntax (date)))
+(define *compilation-date* %date)
+@end example
 
-Internally, Guile represents macros using a disjoint type.
+It works at a REPL because the expressions are evaluated one-by-one, in order,
+but if placed in a file, the expressions are expanded one-by-one, but not
+evaluated until the compiled file is loaded.
+
+The fix is to use @code{eval-when}.
+
+@example
+;; correct: using eval-when
+(use-modules (srfi srfi-19))
+(eval-when (compile load eval)
+  (define (date) (date->string (current-date))))
+(define-syntax %date (identifier-syntax (date)))
+(define *compilation-date* %date)
+@end example
+
+@deffn {Syntax} eval-when conditions exp...
+Evaluate @var{exp...} under the given @var{conditions}. Valid conditions include
+@code{eval}, @code{load}, and @code{compile}. If you need to use
+@code{eval-when}, use it with all three conditions, as in the above example.
+Other uses of @code{eval-when} may void your warranty or poison your cat.
+@end deffn
+
+@node Internal Macros
+@subsection Internal Macros
 
 @deffn {Scheme Procedure} make-syntax-transformer name type binding
+Construct a syntax transformer object. This is part of Guile's low-level support
+for syntax-case.
 @end deffn
 
 @deffn {Scheme Procedure} macro? obj
 @deffnx {C Function} scm_macro_p (obj)
-Return @code{#t} if @var{obj} is a regular macro, a memoizing macro, a
-syntax transformer, or a syntax-case macro.
+Return @code{#t} iff @var{obj} is a syntax transformer.
+
+Note that it's a bit difficult to actually get a macro as a first-class object;
+simply naming it (like @code{case}) will produce a syntax error. But it is
+possible to get these objects using @code{module-ref}:
+
+@example
+(macro? (module-ref (current-module) 'case))
+@result{} #t
+@end example
 @end deffn
 
 @deffn {Scheme Procedure} macro-type m
 @deffnx {C Function} scm_macro_type (m)
-Return one of the symbols @code{syntax}, @code{macro},
-@code{macro!}, or @code{syntax-case}, depending on whether
-@var{m} is a syntax transformer, a regular macro, a memoizing
-macro, or a syntax-case macro, respectively.  If @var{m} is
-not a macro, @code{#f} is returned.
+Return the @var{type} that was given when @var{m} was constructed, via
+@code{make-syntax-transformer}.
 @end deffn
 
 @deffn {Scheme Procedure} macro-name m
@@ -766,16 +860,18 @@ not a macro, @code{#f} is returned.
 Return the name of the macro @var{m}.
 @end deffn
 
-@deffn {Scheme Procedure} macro-transformer m
-@deffnx {C Function} scm_macro_transformer (m)
-Return the transformer of the macro @var{m}.
-@end deffn
-
 @deffn {Scheme Procedure} macro-binding m
 @deffnx {C Function} scm_macro_binding (m)
 Return the binding of the macro @var{m}.
 @end deffn
 
+@deffn {Scheme Procedure} macro-transformer m
+@deffnx {C Function} scm_macro_transformer (m)
+Return the transformer of the macro @var{m}. This will return a procedure, for
+which one may ask the docstring. That's the whole reason this section is
+documented. Actually a part of the result of @code{macro-binding}.
+@end deffn
+
 
 @c Local Variables:
 @c TeX-master: "guile.texi"