guile-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

guile/guile-core/doc ChangeLog scheme-data.texi...


From: Neil Jerram
Subject: guile/guile-core/doc ChangeLog scheme-data.texi...
Date: Sat, 05 May 2001 06:40:18 -0700

CVSROOT:        /cvs
Module name:    guile
Changes by:     Neil Jerram <address@hidden>    01/05/05 06:40:18

Modified files:
        guile-core/doc : ChangeLog scheme-data.texi 
                         scheme-procedures.texi 

Log message:
        * New material on macros.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/guile/guile-core/doc/ChangeLog.diff?cvsroot=OldCVS&tr1=1.82&tr2=1.83&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/guile/guile-core/doc/scheme-data.texi.diff?cvsroot=OldCVS&tr1=1.16&tr2=1.17&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/guile/guile-core/doc/scheme-procedures.texi.diff?cvsroot=OldCVS&tr1=1.9&tr2=1.10&r1=text&r2=text

Patches:
Index: guile/guile-core/doc/ChangeLog
diff -u guile/guile-core/doc/ChangeLog:1.82 guile/guile-core/doc/ChangeLog:1.83
--- guile/guile-core/doc/ChangeLog:1.82 Fri May  4 14:53:59 2001
+++ guile/guile-core/doc/ChangeLog      Sat May  5 06:40:18 2001
@@ -1,3 +1,11 @@
+2001-05-05  Neil Jerram  <address@hidden>
+
+       * scheme-procedures.texi (Macros, Syntax Rules, Internal Macros):
+       New material.
+       (Syntax Case): New node, but currently empty.
+
+       * scheme-data.texi (Booleans, Symbols): Supply cross-references.
+
 2001-05-04  Neil Jerram  <address@hidden>
 
        * new-docstrings.texi, posix.texi, scheme-control.texi,
Index: guile/guile-core/doc/scheme-data.texi
diff -u guile/guile-core/doc/scheme-data.texi:1.16 
guile/guile-core/doc/scheme-data.texi:1.17
--- guile/guile-core/doc/scheme-data.texi:1.16  Fri May  4 14:53:59 2001
+++ guile/guile-core/doc/scheme-data.texi       Sat May  5 06:40:18 2001
@@ -69,7 +69,8 @@
 Boolean values are returned by predicate procedures, such as the general
 equality predicates @code{eq?}, @code{eqv?} and @code{equal?}
 (@pxref{Equality}) and numerical and string comparison operators like
address@hidden (REFFIXME) and @code{<=} (REFFIXME).
address@hidden (@pxref{String Comparison}) and @code{<=}
+(@pxref{Comparison}).
 
 @lisp
 (<= 3 8)
@@ -89,8 +90,8 @@
 #t
 @end lisp
 
-In test condition contexts like @code{if} (REFFIXME) and @code{cond}
-(REFFIXME), where a group of subexpressions will be evaluated only if a
+In test condition contexts like @code{if} and @code{cond} (@pxref{if
+cond case}), where a group of subexpressions will be evaluated only if a
 @var{condition} expression evaluates to ``true'', ``true'' means any
 value at all except @code{#f}.
 
@@ -2312,9 +2313,9 @@
 information for the human reader than, say, numbers.
 
 It is very common in Scheme programs to use symbols as keys in
-association lists (REFFIXME) or hash tables (REFFIXME), because this
-usage improves the readability a lot, and does not cause any performance
-loss.
+association lists (@pxref{Association Lists}) or hash tables
+(@pxref{Hash Tables}), because this usage improves the readability a
+lot, and does not cause any performance loss.
 
 The read syntax for symbols is a sequence of letters, digits, and
 @emph{extended alphabetic characters} that begins with a character that
@@ -2329,10 +2330,10 @@
 @end example
 
 In addition to the read syntax defined above (which is taken from R5RS
-(REFFIXME)), Guile provides a method for writing symbols with unusual
-characters, such as space characters.  If you (for whatever reason) need
-to write a symbol containing characters not mentioned above, you write
-symbols as follows:
+(@pxref{Formal syntax,,,r5rs,The Revised^5 Report on Scheme})), Guile
+provides a method for writing symbols with unusual characters, such as
+space characters.  If you (for whatever reason) need to write a symbol
+containing characters not mentioned above, you write symbols as follows:
 
 @itemize @bullet
 @item
Index: guile/guile-core/doc/scheme-procedures.texi
diff -u guile/guile-core/doc/scheme-procedures.texi:1.9 
guile/guile-core/doc/scheme-procedures.texi:1.10
--- guile/guile-core/doc/scheme-procedures.texi:1.9     Fri May  4 14:54:00 2001
+++ guile/guile-core/doc/scheme-procedures.texi Sat May  5 06:40:18 2001
@@ -7,7 +7,10 @@
 * Optional Arguments::          Handling keyword, optional and rest arguments.
 * Procedure Properties::        Procedure properties and metainformation.
 * Procedures with Setters::     Procedures with setters.
-* Macros::                      Macros.
+* 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
 
 
@@ -500,54 +503,249 @@
 
 
 @node Macros
address@hidden Macros
address@hidden Lisp Style Macro Definitions
 
-[FIXME: This needs some more text on the difference between procedures,
-macros and memoizing macros.  Also, any definitions listed here should
-be double-checked by someone who knows what's going on.  Ask Mikael, Jim
-or Aubrey for help. -twp]
address@hidden macros
address@hidden 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:
 
address@hidden primitive procedure->syntax code
-Return a @dfn{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.
address@hidden deffn
address@hidden
+(@var{macro-name} @var{macro-args} @dots{})
address@hidden lisp
 
address@hidden primitive procedure->macro code
-Return a @dfn{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.  The value returned from @var{code} which has been
-passed to @code{procedure->memoizing-macro} replaces the form
-passed to @var{code}.  For example:
+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
address@hidden, and in Scheme, @code{define-macro} rather than
address@hidden
 
address@hidden defmacro
address@hidden 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
-(define trace
-  (procedure->macro
-   (lambda (x env) `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x))))))
+(defmacro @var{name} (@var{args} @dots{}) @var{body} @dots{})
address@hidden lisp
+
address@hidden
+is the same as
+
address@hidden
+(define-macro (@var{name} @var{args} @dots{}) @var{body} @dots{})
address@hidden lisp
+
address@hidden
+The difference is analogous to the corresponding difference between
+Lisp's @code{defun} and Scheme's @code{define}.
+
address@hidden, from the @file{boot-9.scm} file in the Guile
+distribution, is a good example of macro definition using
address@hidden:
+
address@hidden
+(defmacro false-if-exception (expr)
+  `(catch #t
+          (lambda () ,expr)
+          (lambda args #f)))
address@hidden lisp
+
address@hidden
+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:
+
address@hidden
+(false-if-exception (open-input-file "may-not-exist"))
address@hidden
+(catch #t
+       (lambda () (open-input-file "may-not-exist"))
+       (lambda args #f))
address@hidden lisp
+
+
address@hidden Syntax Rules
address@hidden The R5RS @code{syntax-rules} System
+
+R5RS defines an alternative system for macro and syntax transformations
+using the keywords @code{define-syntax}, @code{let-syntax},
address@hidden 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
+
address@hidden @bullet
address@hidden
+does not require complicated quoting and extraction of components of the
+source expression using @code{caddr} etc.
+
address@hidden
+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.
address@hidden itemize
+
address@hidden
+The last point is commonly referred to as being @dfn{hygienic}: the R5RS
address@hidden 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:
+
address@hidden
+(syntax-rules ()
+  ((_ expr)
+   (catch #t
+          (lambda () expr)
+          (lambda args #f))))
address@hidden lisp
+
+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-modules (ice-9 syncase))} or
address@hidden(use-syntax (ice-9 syncase))} (@pxref{Loading Guile Modules})
+before the first usage of @code{define-syntax} etc.  If you are writing
+a Scheme module, you can alternatively use one of the keywords
address@hidden:use-module} and @code{#:use-syntax} in your @code{define-module}
+declaration (@pxref{Creating Guile Modules}).
+
address@hidden
+* Pattern Language::            The @code{syntax-rules} pattern language.
+* Define-Syntax::               Top level syntax definitions.
+* Let-Syntax::                  Local syntax definitions.
address@hidden menu
+
+
address@hidden Pattern Language
address@hidden The @code{syntax-rules} Pattern Language
+
+
address@hidden Define-Syntax
address@hidden Top Level Syntax Definitions
+
+define-syntax:  The gist is
+
+  (define-syntax <keyword> <transformer-spec>)
+
+makes the <keyword> into a macro so that
+
+  (<keyword> ...)
+
+expands at _compile_ or _read_ time (i.e. before any
+evaluation begins) into some expression that is
+given by the <transformer-spec>.
+
+
address@hidden Let-Syntax
address@hidden Local Syntax Definitions
+
+
address@hidden Syntax Case
address@hidden Support for the @code{syntax-case} System
+
+
+
address@hidden Internal Macros
address@hidden Internal Representation of Macros and Syntax
 
-(trace @i{foo}) @equiv{} (set! @i{foo} (tracef @i{foo} '@i{foo})).
+Internally, Guile uses three different flavours of macros.  The three
+flavours are called @dfn{acro} (or @dfn{syntax}), @dfn{macro} and
address@hidden
+
+Given the expression
+
address@hidden
+(foo @dots{})
 @end lisp
+
address@hidden
+with @code{foo} being some flavour of macro, one of the following things
+will happen when the expression is evaluated.
+
address@hidden
address@hidden
+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.
+
address@hidden
+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.
+
address@hidden
+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.
address@hidden 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
address@hidden) 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
address@hidden>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
address@hidden (@pxref{Syntax Rules}) instead.  (In low level
+terms, @code{defmacro}, @code{define-macro} and @code{define-syntax} are
+all implemented as mmacros.)
+
address@hidden primitive procedure->syntax 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
 
address@hidden primitive procedure->memoizing-macro code
-Return a @dfn{macro} which, when a symbol defined to this value
-appears as the first symbol in an expression, evaluates the
-result of applying @var{proc} to the expression and the
-environment.  The value returned from @var{proc} which has been
-passed to @code{procedure->memoizing-macro} replaces the form
-passed to @var{proc}.  For example:
address@hidden primitive procedure->macro 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
address@hidden to the expression and the environment.  For example:
 
 @lisp
 (define trace
   (procedure->macro
-   (lambda (x env) `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x))))))
+    (lambda (x env)
+      `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x))))))
 
-(trace @i{foo}) @equiv{} (set! @i{foo} (tracef @i{foo} '@i{foo})).
+(trace @i{foo})
address@hidden
+(set! @i{foo} (tracef @i{foo} '@i{foo})).
 @end lisp
 @end deffn
 
address@hidden primitive procedure->memoizing-macro 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
address@hidden to the expression and the environment.
address@hidden>memoizing-macro} is the same as
address@hidden>macro}, except that the expression returned by
address@hidden replaces the original macro expression in the memoized form
+of the containing code.
address@hidden deffn
+
+In the following primitives, @dfn{acro} flavour macros are referred to
+as @dfn{syntax transformers}.
+
 @deffn primitive macro? obj
 Return @code{#t} if @var{obj} is a regular macro, a memoizing macro or a
 syntax transformer.
@@ -556,7 +754,7 @@
 @deffn primitive macro-type m
 Return one of the symbols @code{syntax}, @code{macro} or
 @code{macro!}, depending on whether @var{m} is a syntax
-tranformer, a regular macro, or a memoizing macro,
+transformer, a regular macro, or a memoizing macro,
 respectively.  If @var{m} is not a macro, @code{#f} is
 returned.
 @end deffn



reply via email to

[Prev in Thread] Current Thread [Next in Thread]