From e4955559c6f541c32811c5caaa9b0224abb2c85a Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Thu, 18 Mar 2010 23:39:33 +0100 Subject: [PATCH] A start at syntax-rules docs * doc/ref/api-macros.texi: New file, documenting macros. Removed some old cruft, and started documenting hygienic macros. * doc/ref/api-procedures.texi: Moved macro things out of here. * doc/ref/guile.texi: Separate macros from procedures. * doc/ref/api-data.texi: Update some xrefs. * doc/ref/Makefile.am: Add api-macros.texi. --- doc/ref/Makefile.am | 1 + doc/ref/api-data.texi | 2 +- doc/ref/api-macros.texi | 474 ++++++++++++++++++++++++++++++++++++ doc/ref/api-procedures.texi | 294 +--------------------- doc/ref/guile.texi | 4 +- 5 files changed, 482 insertions(+), 293 deletions(-) create mode 100644 doc/ref/api-macros.texi diff --git a/doc/ref/Makefile.am b/doc/ref/Makefile.am index 5e9c5b5ad..7ed92f2da 100644 --- a/doc/ref/Makefile.am +++ b/doc/ref/Makefile.am @@ -35,6 +35,7 @@ guile_TEXINFOS = preface.texi \ scheme-ideas.texi \ api-data.texi \ api-procedures.texi \ + api-macros.texi \ api-utility.texi \ api-binding.texi \ api-control.texi \ diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index 8153a5d1b..8b6bc1fa4 100755 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -5860,7 +5860,7 @@ Equivalent to @code{scm_symbol_to_keyword (scm_from_locale_symbol @subsection ``Functionality-Centric'' Data Types Procedures and macros are documented in their own chapter: see -@ref{Procedures and Macros}. +@ref{Procedures} and @ref{Macros}. Variable objects are documented as part of the description of Guile's module system: see @ref{Variables}. diff --git a/doc/ref/api-macros.texi b/doc/ref/api-macros.texi new file mode 100644 index 000000000..bd81ba306 --- /dev/null +++ b/doc/ref/api-macros.texi @@ -0,0 +1,474 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Macros +@section Macros + +At its best, programming in Lisp is an iterative process of building up a +language appropriate to the problem at hand, and then solving the problem in +that language. Defining new procedures is part of that, but Lisp also allows +the user to extend its syntax, with its famous @dfn{macros}. + +@cindex macros +@cindex transformation +Macros are syntactic extensions which cause the expression that they appear in +to be transformed in some way @emph{before} being evaluated. In expressions that +are intended for macro transformation, the identifier that names the relevant +macro must appear as the first element, like this: + +@lisp +(@var{macro-name} @var{macro-args} @dots{}) +@end lisp + +@cindex macro expansion +Macro expansion is a separate phase of evaluation, run before code is +interpreted or compiled. A macro is a program that runs on programs, translating +an embedded language into core Scheme. + +@menu +* Defining Macros:: Binding macros, globally and locally. +* Syntax Rules:: Pattern-driven macros. +* Syntax Case:: Procedural, hygienic macros. +* Defmacros:: Lisp-style macros. +* Identifier Macros:: Identifier macros. +* Eval When:: Affecting the expand-time environment. +* Internal Macros:: Macros as first-class values. +@end menu + +@node Defining Macros +@subsection Defining Macros + +A macro is a binding between a keyword and a syntax transformer. Since it's +difficult to discuss @code{define-syntax} without discussing the format of +transformers, consider the following example macro definition: + +@example +(define-syntax when + (syntax-rules () + ((when condition exp ...) + (if condition + (begin exp ...))))) + +(when #t + (display "hey ho\n") + (display "let's go\n")) +@print{} hey ho +@print{} let's go +@end example + +In this example, the @code{when} binding is bound with @code{define-syntax}. +Syntax transformers are discussed in more depth in @ref{Syntax Rules} and +@ref{Syntax Case}. + +@deffn {Syntax} define-syntax keyword transformer +Bind @var{keyword} to the syntax transformer obtained by evaluating +@var{transformer}. + +After a macro has been defined, further instances of @var{keyword} in Scheme +source code will invoke the syntax transformer defined by @var{transformer}. +@end deffn + +One can also establish local syntactic bindings with @code{let-syntax}. + +@deffn {Syntax} let-syntax ((keyword transformer) ...) exp... +Bind @var{keyword...} to @var{transformer...} while expanding @var{exp...}. + +A @code{let-syntax} binding only exists at expansion-time. + +@example +(let-syntax ((unless + (syntax-rules () + ((unless condition exp ...) + (if (not condition) + (begin exp ...)))))) + (unless #t + (primitive-exit 1)) + "rock rock rock") +@result{} "rock rock rock" +@end example +@end deffn + +A @code{define-syntax} form is valid anywhere a definition may appear: at the +top-level, or locally. Just as a local @code{define} expands out to an instance +of @code{letrec}, a local @code{define-syntax} expands out to +@code{letrec-syntax}. + +@deffn {Syntax} letrec-syntax ((keyword transformer) ...) exp... +Bind @var{keyword...} to @var{transformer...} while expanding @var{exp...}. + +In the spirit of @code{letrec} versus @code{let}, an expansion produced by +@var{transformer} may reference a @var{keyword} bound by the +same @var{letrec-syntax}. + +@example +(letrec-syntax ((my-or + (syntax-rules () + ((my-or) + #t) + ((my-or exp) + exp) + ((my-or exp rest ...) + (let ((t exp)) + (if exp + exp + (my-or rest ...))))))) + (my-or #f "rockaway beach")) +@result{} "rockaway beach" +@end example +@end deffn + +@node Syntax Rules +@subsection Syntax-rules Macros + +@code{syntax-rules} macros are simple, pattern-driven syntax transformers, with +a beauty worthy of Scheme. + +@deffn {Syntax} syntax-rules literals (pattern template)... +A @code{syntax-rules} macro consists of three parts: the literals (if any), the +patterns, and as many templates as there are patterns. + +When the syntax expander sees the invocation of a @code{syntax-rules} macro, it +matches the expression against the patterns, in order, and rewrites the +expression using the template from the first matching pattern. If no pattern +matches, a syntax error is signalled. +@end deffn + +@subsubsection Patterns + +We have already seen some examples of patterns in the previous section: +@code{(unless condition exp ...)}, @code{(my-or exp)}, and so on. A pattern is +structured like the expression that it is to match. It can have nested structure +as well, like @code{(let ((var val) ...) exp exp* ...)}. Broadly speaking, +patterns are made of lists, improper lists, vectors, identifiers, and datums. +Users can match a sequence of patterns using the ellipsis (@code{...}). + +Identifiers in a pattern are called @dfn{literals} if they are present in the +@code{syntax-rules} literals list, and @dfn{pattern variables} otherwise. When +building up the macro output, the expander replaces instances of a pattern +variable in the template with the matched subexpression. + +@example +(define-syntax kwote + (syntax-rules () + ((kwote exp) + (quote exp)))) +(kwote (foo . bar)) +@result{} (foo . bar) +@end example + +An improper list of patterns matches as rest arguments do: + +@example +(define-syntax let1 + (syntax-rules () + ((_ (var val) . exps) + (let ((var val)) . exps)))) +@end example + +However this definition of @code{let1} probably isn't what you want, as the tail +pattern @var{exps} will match non-lists, like @code{(let1 (foo 'bar) . baz)}. So +often instead of using improper lists as patterns, ellipsized patterns are +better. Instances of a pattern variable in the template must be followed by an +ellipsis. + +@example +(define-syntax let1 + (syntax-rules () + ((_ (var val) exp ...) + (let ((var val)) exp ...)))) +@end example + +This @code{let1} probably still doesn't do what we want, because the body +matches sequences of zero expressions, like @code{(let1 (foo 'bar))}. In this +case we need to assert we have at least one body expression. A common idiom for +this is to name the ellipsized pattern variable with an asterisk: + +@example +(define-syntax let1 + (syntax-rules () + ((_ (var val) exp exp* ...) + (let ((var val)) exp exp* ...)))) +@end example + +A vector of patterns matches a vector whose contents match the patterns, +including ellipsizing and tail patterns. + +@example +(define-syntax letv + (syntax-rules () + ((_ #((var val) ...) exp exp* ...) + (let ((var val) ...) exp exp* ...)))) +(letv #((foo 'bar)) foo) +@result{} foo +@end example + +Literals are used to match specific datums in an expression, like the use of +@code{=>} and @code{else} in @code{cond} expressions. + +@example +(define-syntax cond1 + (syntax-rules (=> else) + ((cond1 test => fun) + (let ((exp test)) + (if exp (fun exp) #f))) + ((cond1 test exp exp* ...) + (if test (begin exp exp* ...))) + ((cond1 else exp exp* ...) + (begin exp exp* ...)))) + +(define (square x) (* x x)) +(cond1 10 => square) +@result{} 100 +(let ((=> #t)) + (cond1 10 => square)) +@result{} # +@end example + +A literal matches an input expression if the input expression is an identifier +with the same name as the literal, and both are unbound@footnote{Language +lawyers probably see the need here for use of @code{literal-identifier=?} rather +than @code{free-identifier=?}, and would probably be correct. Patches +accepted.}. + +If a pattern is not a list, vector, or an identifier, it matches as a literal, +with @code{equal?}. + +@example +(define-syntax define-matcher-macro + (syntax-rules () + ((_ name lit) + (define-syntax name + (syntax-rules () + ((_ lit) #t) + ((_ else) #f)))))) + +(define-matcher-macro is-literal-foo? "foo") + +(is-literal-foo? "foo") +@result{} #t +(is-literal-foo? "bar") +@result{} #f +(let ((foo "foo")) + (is-literal-foo? foo)) +@result{} #f +@end example + +The last example indicates that matching happens at expansion-time, not +at run-time. + +Syntax-rules macros are always used as @code{(@var{macro} . @var{args})}, and +the @var{macro} will always be a symbol. Correspondingly, a @code{syntax-rules} +pattern must be a list (proper or improper), and the first pattern in that list +must be an identifier. Incidentally it can be any identifier -- it doesn't have +to actually be the name of the macro. Thus the following three are equivalent: + +@example +(define-syntax when + (syntax-rules () + ((when c e ...) + (if c (begin e ...))))) + +(define-syntax when + (syntax-rules () + ((_ c e ...) + (if c (begin e ...))))) + +(define-syntax when + (syntax-rules () + ((something-else-entirely c e ...) + (if c (begin e ...))))) +@end example + +For clarity, use one of the first two variants. Also note that since the pattern +variable will always match the macro itself (e.g., @code{cond1}), it is actually +left unbound in the template. + +@subsubsection Hygiene + +@code{syntax-rules} macros have a magical property: they preserve referential +transparency. When you read a macro definition, any free bindings in that macro +are resolved relative to the macro definition; and when you read a macro +instantiation, all free bindings in that expression are resolved relative to the +expression. + +This property is sometimes known as @dfn{hygiene}, and it does aid in code +cleanliness. In your macro definitions, you can feel free to introduce temporary +variables, without worrying about inadvertantly introducing bindings into the +macro expansion. + +Consider the definition of @code{my-or} from the previous section: + +@example +(define-syntax my-or + (syntax-rules () + ((my-or) + #t) + ((my-or exp) + exp) + ((my-or exp rest ...) + (let ((t exp)) + (if exp + exp + (my-or rest ...)))))) +@end example + +A naive expansion of @code{(let ((t #t)) (my-or #f t))} would yield: + +@example +(let ((t #t)) + (let ((t #f)) + (if t t t))) +@result{} #f +@end example + +@noindent +Which clearly is not what we want. Somehow the @code{t} in the definition is +distinct from the @code{t} at the site of use; and it is indeed this distinction +that is maintained by the syntax expander, when expanding hygienic macros. + +This discussion is mostly relevant in the context of traditional Lisp macros +(@pxref{Defmacros}), which do not preserve referential transparency. Hygiene +adds to the expressive power of Scheme. + +@subsubsection Further Information + +For a formal definition of @code{syntax-rules} and its pattern language, see +@xref{Macros, , Macros, r5rs, Revised(5) Report on the Algorithmic Language +Scheme}. + +@code{syntax-rules} macros are simple and clean, but do they have limitations. +They do not lend themselves to expressive error messages: patterns either match +or they don't. Their ability to generate code is limited to template-driven +expansion; often one needs to define a number of helper macros to get real work +done. Sometimes one wants to introduce a binding into the lexical context of the +generated code; this is impossible with @code{syntax-rules}. Relatedly, they +cannot programmatically generate identifiers. + +The solution to all of these problems is to use @code{syntax-case} if you need +its features. But if for some reason you're stuck with @code{syntax-rules}, you +might enjoy Joe Marshall's +@uref{http://sites.google.com/site/evalapply/eccentric.txt,@code{syntax-rules} +Primer for the Merely Eccentric}. + +@node Syntax Case +@subsection Support for the @code{syntax-case} System + +@node Defmacros +@subsection Lisp-style Macro Definitions + +In Lisp-like languages, the traditional way to define macros is very +similar to procedure definitions. The key differences are that the +macro definition body should return a list that describes the +transformed expression, and that the definition is marked as a macro +definition (rather than a procedure definition) by the use of a +different definition keyword: in Lisp, @code{defmacro} rather than +@code{defun}, and in Scheme, @code{define-macro} rather than +@code{define}. + +@fnindex defmacro +@fnindex define-macro +Guile supports this style of macro definition using both @code{defmacro} +and @code{define-macro}. The only difference between them is how the +macro name and arguments are grouped together in the definition: + +@lisp +(defmacro @var{name} (@var{args} @dots{}) @var{body} @dots{}) +@end lisp + +@noindent +is the same as + +@lisp +(define-macro (@var{name} @var{args} @dots{}) @var{body} @dots{}) +@end lisp + +@noindent +The difference is analogous to the corresponding difference between +Lisp's @code{defun} and Scheme's @code{define}. + +@code{false-if-exception}, from the @file{boot-9.scm} file in the Guile +distribution, is a good example of macro definition using +@code{defmacro}: + +@lisp +(defmacro false-if-exception (expr) + `(catch #t + (lambda () ,expr) + (lambda args #f))) +@end lisp + +@noindent +The effect of this definition is that expressions beginning with the +identifier @code{false-if-exception} are automatically transformed into +a @code{catch} expression following the macro definition specification. +For example: + +@lisp +(false-if-exception (open-input-file "may-not-exist")) +@equiv{} +(catch #t + (lambda () (open-input-file "may-not-exist")) + (lambda args #f)) +@end lisp + +@deffn {Scheme Procedure} cons-source xorig x y +@deffnx {C Function} scm_cons_source (xorig, x, y) +Create and return a new pair whose car and cdr are @var{x} and @var{y}. +Any source properties associated with @var{xorig} are also associated +with the new pair. +@end deffn + + +@node Identifier Macros +@subsection Identifier Macros + +@node Eval When +@subsection Eval-when + +@node Internal Macros +@subsection Internal Macros + + +Internally, Guile represents macros using a disjoint type. + +@deffn {Scheme Procedure} make-syntax-transformer name type binding +@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. +@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. +@end deffn + +@deffn {Scheme Procedure} macro-name m +@deffnx {C Function} scm_macro_name (m) +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 + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-procedures.texi b/doc/ref/api-procedures.texi index 535d05907..48d1c3f91 100644 --- a/doc/ref/api-procedures.texi +++ b/doc/ref/api-procedures.texi @@ -1,12 +1,12 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009 +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @page -@node Procedures and Macros -@section Procedures and Macros +@node Procedures +@section Procedures @menu * Lambda:: Basic procedure creation using lambda. @@ -16,10 +16,6 @@ * Case-lambda:: One function, multiple arities. * Procedure Properties:: Procedure properties and meta-information. * Procedures with Setters:: Procedures with setters. -* Macros:: Lisp style macro definitions. -* Syntax Rules:: Support for R5RS @code{syntax-rules}. -* Syntax Case:: Support for the @code{syntax-case} system. -* Internal Macros:: Guile's internal representation. @end menu @@ -778,290 +774,6 @@ setter or an operator struct. @end deffn -@node Macros -@subsection Lisp Style Macro Definitions - -@cindex macros -@cindex transformation -Macros are objects which cause the expression that they appear in to be -transformed in some way @emph{before} being evaluated. In expressions -that are intended for macro transformation, the identifier that names -the relevant macro must appear as the first element, like this: - -@lisp -(@var{macro-name} @var{macro-args} @dots{}) -@end lisp - -In Lisp-like languages, the traditional way to define macros is very -similar to procedure definitions. The key differences are that the -macro definition body should return a list that describes the -transformed expression, and that the definition is marked as a macro -definition (rather than a procedure definition) by the use of a -different definition keyword: in Lisp, @code{defmacro} rather than -@code{defun}, and in Scheme, @code{define-macro} rather than -@code{define}. - -@fnindex defmacro -@fnindex define-macro -Guile supports this style of macro definition using both @code{defmacro} -and @code{define-macro}. The only difference between them is how the -macro name and arguments are grouped together in the definition: - -@lisp -(defmacro @var{name} (@var{args} @dots{}) @var{body} @dots{}) -@end lisp - -@noindent -is the same as - -@lisp -(define-macro (@var{name} @var{args} @dots{}) @var{body} @dots{}) -@end lisp - -@noindent -The difference is analogous to the corresponding difference between -Lisp's @code{defun} and Scheme's @code{define}. - -@code{false-if-exception}, from the @file{boot-9.scm} file in the Guile -distribution, is a good example of macro definition using -@code{defmacro}: - -@lisp -(defmacro false-if-exception (expr) - `(catch #t - (lambda () ,expr) - (lambda args #f))) -@end lisp - -@noindent -The effect of this definition is that expressions beginning with the -identifier @code{false-if-exception} are automatically transformed into -a @code{catch} expression following the macro definition specification. -For example: - -@lisp -(false-if-exception (open-input-file "may-not-exist")) -@equiv{} -(catch #t - (lambda () (open-input-file "may-not-exist")) - (lambda args #f)) -@end lisp - - -@node Syntax Rules -@subsection The R5RS @code{syntax-rules} System -@cindex R5RS syntax-rules system - -R5RS defines an alternative system for macro and syntax transformations -using the keywords @code{define-syntax}, @code{let-syntax}, -@code{letrec-syntax} and @code{syntax-rules}. - -The main difference between the R5RS system and the traditional macros -of the previous section is how the transformation is specified. In -R5RS, rather than permitting a macro definition to return an arbitrary -expression, the transformation is specified in a pattern language that - -@itemize @bullet -@item -does not require complicated quoting and extraction of components of the -source expression using @code{caddr} etc. - -@item -is designed such that the bindings associated with identifiers in the -transformed expression are well defined, and such that it is impossible -for the transformed expression to construct new identifiers. -@end itemize - -@noindent -The last point is commonly referred to as being @dfn{hygienic}: the R5RS -@code{syntax-case} system provides @dfn{hygienic macros}. - -For example, the R5RS pattern language for the @code{false-if-exception} -example of the previous section looks like this: - -@lisp -(syntax-rules () - ((_ expr) - (catch #t - (lambda () expr) - (lambda args #f)))) -@end lisp - -@cindex @code{syncase} -In Guile, the @code{syntax-rules} system is provided by the @code{(ice-9 -syncase)} module. To make these facilities available in your code, -include the expression @code{(use-syntax (ice-9 syncase))} (@pxref{Using -Guile Modules}) before the first usage of @code{define-syntax} etc. If -you are writing a Scheme module, you can alternatively include the form -@code{#:use-syntax (ice-9 syncase)} in your @code{define-module} -declaration (@pxref{Creating Guile Modules}). - -@menu -* Pattern Language:: The @code{syntax-rules} pattern language. -* Define-Syntax:: Top level syntax definitions. -* Let-Syntax:: Local syntax definitions. -@end menu - - -@node Pattern Language -@subsubsection The @code{syntax-rules} Pattern Language - - -@node Define-Syntax -@subsubsection Top Level Syntax Definitions - -define-syntax: The gist is - - (define-syntax ) - -makes the into a macro so that - - ( ...) - -expands at _compile_ or _read_ time (i.e. before any -evaluation begins) into some expression that is -given by the . - - -@node Let-Syntax -@subsubsection Local Syntax Definitions - - -@node Syntax Case -@subsection Support for the @code{syntax-case} System - - - -@node Internal Macros -@subsection Internal Representation of Macros and Syntax - -[FIXME: used to be true. Isn't any more. Use syntax-rules or -syntax-case please :)] - -Internally, Guile uses three different flavors of macros. The three -flavors are called @dfn{acro} (or @dfn{syntax}), @dfn{macro} and -@dfn{mmacro}. - -Given the expression - -@lisp -(foo @dots{}) -@end lisp - -@noindent -with @code{foo} being some flavor of macro, one of the following things -will happen when the expression is evaluated. - -@itemize @bullet -@item -When @code{foo} has been defined to be an @dfn{acro}, the procedure used -in the acro definition of @code{foo} is passed the whole expression and -the current lexical environment, and whatever that procedure returns is -the value of evaluating the expression. You can think of this a -procedure that receives its argument as an unevaluated expression. - -@item -When @code{foo} has been defined to be a @dfn{macro}, the procedure used -in the macro definition of @code{foo} is passed the whole expression and -the current lexical environment, and whatever that procedure returns is -evaluated again. That is, the procedure should return a valid Scheme -expression. - -@item -When @code{foo} has been defined to be a @dfn{mmacro}, the procedure -used in the mmacro definition of `foo' is passed the whole expression -and the current lexical environment, and whatever that procedure returns -replaces the original expression. Evaluation then starts over from the -new expression that has just been returned. -@end itemize - -The key difference between a @dfn{macro} and a @dfn{mmacro} is that the -expression returned by a @dfn{mmacro} procedure is remembered (or -@dfn{memoized}) so that the expansion does not need to be done again -next time the containing code is evaluated. - -The primitives @code{procedure->syntax}, @code{procedure->macro} and -@code{procedure->memoizing-macro} are used to construct acros, macros -and mmacros respectively. However, if you do not have a very special -reason to use one of these primitives, you should avoid them: they are -very specific to Guile's current implementation and therefore likely to -change. Use @code{defmacro}, @code{define-macro} (@pxref{Macros}) or -@code{define-syntax} (@pxref{Syntax Rules}) instead. (In low level -terms, @code{defmacro}, @code{define-macro} and @code{define-syntax} are -all implemented as mmacros.) - -@deffn {Scheme Procedure} procedure->syntax code -@deffnx {C Function} scm_makacro (code) -Return a macro which, when a symbol defined to this value appears as the -first symbol in an expression, returns the result of applying @var{code} -to the expression and the environment. -@end deffn - -@deffn {Scheme Procedure} procedure->macro code -@deffnx {C Function} scm_makmacro (code) -Return a macro which, when a symbol defined to this value appears as the -first symbol in an expression, evaluates the result of applying -@var{code} to the expression and the environment. For example: - -@lisp -(define trace - (procedure->macro - (lambda (x env) - `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x)))))) - -(trace @i{foo}) -@equiv{} -(set! @i{foo} (tracef @i{foo} '@i{foo})). -@end lisp -@end deffn - -@deffn {Scheme Procedure} procedure->memoizing-macro code -@deffnx {C Function} scm_makmmacro (code) -Return a macro which, when a symbol defined to this value appears as the -first symbol in an expression, evaluates the result of applying -@var{code} to the expression and the environment. -@code{procedure->memoizing-macro} is the same as -@code{procedure->macro}, except that the expression returned by -@var{code} replaces the original macro expression in the memoized form -of the containing code. -@end deffn - -In the following primitives, @dfn{acro} flavor macros are referred to -as @dfn{syntax transformers}. - -@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. -@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. -@end deffn - -@deffn {Scheme Procedure} macro-name m -@deffnx {C Function} scm_macro_name (m) -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} cons-source xorig x y -@deffnx {C Function} scm_cons_source (xorig, x, y) -Create and return a new pair whose car and cdr are @var{x} and @var{y}. -Any source properties associated with @var{xorig} are also associated -with the new pair. -@end deffn - - @c Local Variables: @c TeX-master: "guile.texi" @c End: diff --git a/doc/ref/guile.texi b/doc/ref/guile.texi index 1c7f62724..2958968a9 100644 --- a/doc/ref/guile.texi +++ b/doc/ref/guile.texi @@ -295,7 +295,8 @@ available through both Scheme and C interfaces. * Simple Data Types:: Numbers, strings, booleans and so on. * Compound Data Types:: Data types for holding other data. * Smobs:: Defining new data types in C. -* Procedures and Macros:: Procedures and macros. +* Procedures:: Procedures. +* Macros:: Extending the syntax of Scheme. * Utility Functions:: General utility functions. * Binding Constructs:: Definitions and variable bindings. * Control Mechanisms:: Controlling the flow of program execution. @@ -319,6 +320,7 @@ available through both Scheme and C interfaces. @include api-compound.texi @include api-smobs.texi @include api-procedures.texi +@include api-macros.texi @include api-utility.texi @include api-binding.texi @include api-control.texi -- 2.20.1