2 November 1991

A compatible low-level macro facility
=====================================

Although the pattern language provided by `syntax-rules' is the
preferred way to specify macro transformers, other low-level facilities
may be provided to specify more complex macro transformers.  In fact,
`syntax-rules' can itself be defined as a macro using the low-level
facilities described in this section.

The low-level macro facility described here introduces `syntax' as a
new syntactic keyword analogous to `quote', and allows a <transformer
spec> to be any expression.  This is accomplished by adding the
following two productions to the productions in section Formal syntax
and in section Binding syntactic keywords above.

<expression> --> (syntax <datum>)
<transformer spec> --> <expression>

The low-level macro system also adds the following procedures:

     unwrap-syntax          identifier->symbol
     identifier?            generate-identifier
     free-identifier=?      construct-identifier
     bound-identifier=?

Evaluation of a program proceeds in two logical steps.  First the
program is converted into an intermediate language via macro-expansion,
and then the result of macro expansion is evaluated.  When it is
necessary to distinguish the second stage of this process from the full
evaluation process, it is referred to as "execution."

Syntax definitions, either lexical or global, cause an identifier to be
treated as a keyword within the scope of the binding.  The keyword is
associated with a transformer, which may be created implicitly using
the pattern language of `syntax-rules' or explicitly using the
low-level facilities described below.

Since a transformer spec must be fully evaluated during the course of
expansion, it is necessary to specify the environment in which this
evaluation takes place.  A transformer spec is expanded in the same
environment as that in which the program is being expanded, but is
executed in an environment that is distinct from the environment in
which the program is executed.  This execution environment distinction
is important only for the resolution of global variable references and
assignments.  In what follows, the environment in which transformers
are executed is called the standard transformer environment and is
assumed to be a standard Scheme environment.

Since part of the task of hygienic macro expansion is to resolve
identifier references, the fact that transformers are expanded in the
same environment as the program means that identifier bindings in the
program can shadow identifier uses within transformers.  Since variable
bindings in the program are not available at the time the transformer
is executed, it is an error for a transformer to reference or assign
them.  However, since keyword bindings are available during expansion,
lexically visible keyword bindings from the program may be used in
macro uses in a transformer.

When a macro use is encountered, the macro transformer associated with
the macro keyword is applied to a representation of the macro
expression.  The result returned by the macro transformer replaces the
original expression and is expanded once again.  Thus macro expansions
may themselves be or contain macro uses.

The syntactic representation passed to a macro transformer encapsulates
information about the structure of the represented form and the
bindings of the identifiers it contains.  These syntax objects can be
traversed and examined using the procedures described below.  The
output of a transformer may be built up using the usual Scheme list
constructors, combining pieces of the input with new syntactic
structures.

 - syntax: syntax <datum>
     *Syntax:* The <datum> may be any external representation of a
     Scheme object.

     *Semantics:* `Syntax' is the syntactic analogue of `quote'.  It
     creates a syntactic representation of <datum> that, like an
     argument to a transformer, contains information about the bindings
     for identifiers contained in <datum>.  The binding for an
     identifier introduced by `syntax' is the closest lexically visible
     binding.  All variables and keywords introduced by transformers
     must be created by `syntax'.  It is an error to insert a symbol in
     the output of a transformation procedure unless it is to be part
     of a quoted datum.

     (symbol? (syntax x))                               ==> #f

     (let-syntax ((car (lambda (x) (syntax car))))
       ((car) '(0)))                                    ==> 0

     (let-syntax
       ((quote-quote
         (lambda (x) (list (syntax quote) 'quote))))
       (quote-quote))                                   ==> quote

     (let-syntax
       ((quote-quote
         (lambda (x) (list 'quote 'quote))))
       (quote-quote))                                   ==> *error*

     The second `quote-quote' example results in an error because two
     raw symbols are being inserted in the output.  The quoted `quote'
     in the first `quote-quote' example does not cause an error because
     it will be a quoted datum.

     (let-syntax ((quote-me
                   (lambda (x)
                     (list (syntax quote) x))))
       (quote-me please))                              ==> (quote-me please)

     (let ((x 0))
       (let-syntax ((alpha (lambda (e) (syntax x))))
         (alpha)))                                     ==> 0

     (let ((x 0))
       (let-syntax ((alpha (lambda (x) (syntax x))))
         (alpha)))                                     ==> *error*

     (let-syntax ((alpha
                   (let-syntax ((beta
                                 (syntax-rules ()
                                   ((beta) 0))))
                     (lambda (x) (syntax (beta))))))
       (alpha))                                        ==> *error*

     The last two examples are errors because in both cases a lexically
     bound identifier is placed outside of the scope of its binding.
     In the first case, the variable `x' is placed outside its scope.
     In the second case, the keyword `beta' is placed outside its scope.

     (let-syntax ((alpha (syntax-rules ()
                           ((alpha) 0))))
       (let-syntax ((beta (lambda (x) (alpha))))
         (beta)))                                      ==> 0

     (let ((list 0))
       (let-syntax ((alpha (lambda (x) (list 0))))
         (alpha)))                                     ==> *error*

     The last example is an error because the reference to `list' in the
     transformer is shadowed by the lexical binding for `list'.  Since
     the expansion process is distinct from the execution of the
     program, transformers cannot reference program variables.  On the
     other hand, the previous example is not an error because
     definitions for keywords in the program do exist at expansion time.

          *Note:* It has been suggested that `#'<datum>' and
          `#`<datum>' would be felicitous abbreviations for `(syntax
          <datum>)' and `(quasisyntax <datum>)', respectively, where
          `quasisyntax', which is not described in this appendix, would
          bear the same relationship to `syntax' that `quasiquote'
          bears to `quote'.

 - procedure: identifier? SYNTAX-OBJECT
     Returns #t if SYNTAX-OBJECT represents an identifier, otherwise
     returns #f.

     (identifier? (syntax x))               ==> #t
     (identifier? (quote x))                ==> #f
     (identifier? 3)                        ==> #f

 - procedure: unwrap-syntax SYNTAX-OBJECT
     If SYNTAX-OBJECT is an identifier, then it is returned unchanged.
     Otherwise `unwrap-syntax' converts the outermost structure of
     SYNTAX-OBJECT into a data object whose external representation is
     the same as that of SYNTAX-OBJECT.  The result is either an
     identifier, a pair whose car and cdr are syntax objects, a vector
     whose elements are syntax objects, an empty list, a string, a
     boolean, a character, or a number.

     (identifier? (unwrap-syntax (syntax x)))
                                            ==> #t
     (identifier? (car (unwrap-syntax (syntax (x)))))
                                            ==> #t
     (unwrap-syntax (cdr (unwrap-syntax (syntax (x)))))
                                            ==> ()

 - procedure: free-identifier=? ID1 ID2
     Returns #t if the original occurrences of ID1 and ID2 have the
     same binding, otherwise returns #f.  `free-identifier=?' is used
     to look for a literal identifier in the argument to a transformer,
     such as `else' in a `cond' clause.  A macro definition for
     `syntax-rules' would use `free-identifier=?' to look for literals
     in the input.

     (free-identifier=? (syntax x) (syntax x))
                                            ==> #t
     (free-identifier=? (syntax x) (syntax y))
                                            ==> #f

     (let ((x (syntax x)))
       (free-identifier=? x (syntax x)))
                                            ==> #f

     (let-syntax
       ((alpha
         (lambda (x)
           (free-identifier=? (car (unwrap-syntax x))
                              (syntax alpha)))))
       (alpha))                                        ==> #f

     (letrec-syntax
       ((alpha
         (lambda (x)
           (free-identifier=? (car (unwrap-syntax x))
                              (syntax alpha)))))
       (alpha))                                        ==> #t

 - procedure: bound-identifier=? ID1 ID2
     Returns #t if a binding for one of the two identifiers ID1 and ID2
     would shadow free references to the other, otherwise returns #f.
     Two identifiers can be `free-identifier=?' without being
     `bound-identifier=?'  if they were introduced at different stages
     in the expansion process.  `Bound-identifier=?' can be used, for
     example, to detect duplicate identifiers in bound-variable lists.
     A macro definition of `syntax-rules' would use `bound-identifier=?'
     to look for pattern variables from the input pattern in the output
     template.

     (bound-identifier=? (syntax x) (syntax x))
                                            ==> #t

     (letrec-syntax
       ((alpha
         (lambda (x)
           (bound-identifier=? (car (unwrap-syntax x))
                               (syntax alpha)))))
       (alpha))                                         ==> #f

 - procedure: identifier->symbol ID
     Returns a symbol representing the original name of ID.
     `Identifier->symbol' is used to examine identifiers that appear in
     literal contexts, i.e., identifiers that will appear in quoted
     structures.

     (symbol? (identifier->symbol (syntax x)))
                                            ==> #t
     (identifier->symbol (syntax x))
                                            ==> x

 - procedure: generate-identifier
 - procedure: generate-identifier SYMBOL
     Returns a new identifier.  The optional argument to
     `generate-identifier' specifies the symbolic name of the resulting
     identifier.  If no argument is supplied the name is unspecified.

     `Generate-identifier' is used to introduce bound identifiers into
     the output of a transformer.  Since introduced bound identifiers
     are automatically renamed, `generate-identifier' is necessary only
     for distinguishing introduced identifiers when an indefinite
     number of them must be generated by a macro.

     The optional argument to `generate-identifier' specifies the
     symbolic name of the resulting identifier.  If no argument is
     supplied the name is unspecified.  The procedure
     `identifier->symbol' reveals the symbolic name of an identifier.

     (identifier->symbol (generate-identifier 'x))
                                            ==> x

     (bound-identifier=? (generate-identifier 'x)
                         (generate-identifier 'x))
                                            ==> #f

     (define-syntax set*!
       ; (set*! (<identifier> <expression>) ...)
       (lambda (x)
         (letrec
           ((unwrap-exp
             (lambda (x)
               (let ((x (unwrap-syntax x)))
                 (if (pair? x)
                     (cons (car x)
                           (unwrap-exp (cdr x)))
                     x)))))
           (let ((sets (map unwrap-exp
                            (cdr (unwrap-exp x)))))
             (let ((ids (map car sets))
                   (vals (map cadr sets))
                   (temps (map (lambda (x)
                                 (generate-identifier))
                               sets)))
               `(,(syntax let) ,(map list temps vals)
                 ,@(map (lambda (id temp)
                          `(,(syntax set!) ,id ,temp))
                        ids
                        temps)
                 #f))))))

 - procedure: construct-identifier ID SYMBOL
     Creates and returns an identifier named by SYMBOL that behaves as
     if it had been introduced where the identifier ID was introduced.

     `Construct-identifier' is used to circumvent hygiene by creating
     an identifier that behaves as though it had been implicitly
     present in some expression.  For example, the transformer for a
     structure definition macro might construct the name of a field
     accessor that does not explicitly appear in a use of the macro,
     but can be constructed from the names of the structure and the
     field.  If a binding for the field accessor were introduced by a
     hygienic transformer, then it would be renamed automatically, so
     that the introduced binding would fail to capture any references
     to the field accessor that were present in the input and were
     intended to be within the scope of the introduced binding.

     Another example is a macro that implicitly binds `exit':

     (define-syntax loop-until-exit
       (lambda (x)
         (let ((exit (construct-identifier
                      (car (unwrap-syntax x))
                      'exit))
               (body (car (unwrap-syntax
                           (cdr (unwrap-syntax x))))))
           `(,(syntax call-with-current-continuation)
             (,(syntax lambda)
              (,exit)
              (,(syntax letrec)
               ((,(syntax loop)
                 (,(syntax lambda) ()
                    ,body
                    (,(syntax loop)))))
               (,(syntax loop))))))))

     (let ((x 0) (y 1000))
       (loop-until-exit
        (if (positive? y)
            (begin (set! x (+ x 3))
                   (set! y (- y 1)))
            (exit x)))) => 3000

Acknowledgements
================

The extension described in this appendix is the most sophisticated
macro facility that has ever been proposed for a block-structured
programming language.  The main ideas come from Eugene Kohlbecker's PhD
thesis on hygienic macro expansion [Kohlbecker86], written under the
direction of Dan Friedman [hygienic], and from the work by Alan Bawden
and Jonathan Rees on syntactic closures [Bawden88].  Pattern-directed
macro facilities were popularized by Kent Dybvig's non-hygienic
implementation of `extend-syntax' [Dybvig87].

At the 1988 meeting of this report's authors at Snowbird, a macro
committee consisting of Bawden, Rees, Dybvig, and Bob Hieb was charged
with developing a hygienic macro facility akin to `extend-syntax' but
based on syntactic closures.  Chris Hanson implemented a prototype and
wrote a paper on his experience, pointing out that an implementation
based on syntactic closures must determine the syntactic roles of some
identifiers before macro expansion based on textual pattern matching
can make those roles apparent.  William Clinger observed that
Kohlbecker's algorithm amounts to a technique for delaying this
determination, and proposed a more efficient version of Kohlbecker's
algorithm.  Pavel Curtis spoke up for referentially transparent local
macros.  Rees merged syntactic environments with the modified
Kohlbecker's algorithm and implemented it all, twice [macrosthatwork].

Dybvig and Hieb designed and implemented the low-level macro facility
described above.  Recently Hanson and Bawden have extended syntactic
closures to obtain an alternative low-level macro facility.  The macro
committee has not endorsed any particular low-level facility, but does
endorse the general concept of a low-level facility that is compatible
with the high-level pattern language described in this appendix.

Several other people have contributed by working on macros over the
years.  Hal Abelson contributed by holding this report hostage to the
appendix on macros.

Bibliography
************

   * [Abelson88] Harold Abelson and Gerald Jay Sussman.  Lisp: a
     langauge for stratified design.  *BYTE* 13(2):207-218, February
     1988.

   * [SICP] Harold Abelson and Gerald Jay Sussman with Julie Sussman.
     *Structure and Interpretation of Computer Programs.* MIT Press,
     Cambridge, 1985.

   * [Adams88] Norman Adams and Jonathan Rees.  Object-oriented
     programming in Scheme.  In *Proceedings of the 1988 Conference on
     Lisp   and Functional Programming*, pages 277-288, August 1988.

   * [Bartley86] David H. Bartley and John C. Jensen.  The
     implementation of PC Scheme.  In *Proceedings of the 1986 ACM
     Conference on Lisp   and Functional Programming*, pages 86-93.

   * [Scheme81] John Batali, Edmund Goodhue, Chris Hanson, Howie
     Shrobe, Richard   M. Stallman, and Gerald Jay Sussman.  The
     Scheme-81 architecture--system and chip.  In *Proceedings,
     Conference on Advanced Research in VLSI*,   pages 69-77.  Paul
     Penfield, Jr., editor.  Artech House, 610 Washington Street,
     Dedham MA, 1982.

   * [Bawden88] Alan Bawden and Jonathan Rees.  Syntactic closures.  In
     *Proceedings of the 1988 ACM Symposium on Lisp and   Functional
     Programming*, pages 86-95.

   * [Clinger84] William Clinger.  The Scheme 311 compiler: an exercise
     in denotational semantics.  In *Conference Record of the 1984 ACM
     Symposium on Lisp and   Functional Programming*, pages 356-364.

   * [RRRS] William Clinger, editor.  The revised revised report on
     Scheme, or an uncommon Lisp.  MIT Artificial Intelligence Memo
     848, August 1985.  Also published as Computer Science Department
     Technical Report 174,   Indiana University, June 1985.

   * [Clinger88] William Clinger.  Semantics of Scheme.  *BYTE*
     13(2):221-227, February 1988.

   * [howtoread] William Clinger.  How to read floating point numbers
     accurately.  In *Proceedings of the ACM SIGPLAN '90 Conference
     on Programming Language Design and Implementation*, pages 92-101.
     Proceedings published as *SIGPLAN Notices* 25(6), June 1990.

   * [Clinger85] William Clinger, Daniel P. Friedman, and Mitchell Wand.
     A scheme for a higher-level semantic algebra.  In *Algebraic
     Methods in Semantics*, pages 237-250.  J. Reynolds, M. Nivat,
     editor.  Cambridge University Press, 1985.

   * [Clinger88b] William Clinger, Anne Hartheimer, and Eric Ost.
     Implementation strategies for continuations.  In *Proceedings of
     the 1988 ACM Conference on Lisp and Functional   Programming*,
     pages 124-131.

   * [macrosthatwork] William Clinger and Jonathan Rees.  Macros that
     work.  In *Proceedings of the 1991 ACM Conference on Principles of
      Programming Languages*, pages 155-162.

   * [Curtis90] Pavel Curtis and James Rauen.  A module system for
     Scheme.  In *Proceedings of the 1990 ACM Conference on Lisp and
     Functional Programming*, June 1990.

   * [Dybvig87] R. Kent Dybvig.  *The Scheme Programming Language.*
     Prentice-Hall, 1987.

   * [Dybvig86] R. Kent Dybvig and Daniel P. Friedman and Christopher
     T. Haynes.  Expansion-passing style: a general macro mechanism.
     *Lisp and Symbolic Computation* 1(1):53-76, June 1988.

   * [Dybvig88] R. Kent Dybvig and Robert Hieb.  A variable-arity
     procedural interface.  In *Proceedings of the 1988 ACM Symposium
     on Lisp and   Functional Programming*, pages 106-115.

   * [Dybvig88] R. Kent Dybvig and Robert Hieb.  Engines from
     continuations.  *Journal of Computer Languages* 14(2), pages
     109-123, 1989.

   * [Dybvig88] R. Kent Dybvig and Robert Hieb.  Continuations and
     concurrency.  In *Proceedings of the Second ACM SIGPLAN Notices
     Symposium on Principles and Practice of Parallel Programming*,
     pages 128-136, March 1990.

   * [Eisenberg85] Michael A. Eisenberg.  Bochser: an integrated Scheme
     programming system.  MIT Laboratory for Computer Science Technical
     Report 349,   October 1985.

   * [Eisenberg88] Michael Eisenberg.  Harold Abelson, editor.
     *Programming In Scheme.* Scientific Press, Redwood City,
     California, 1988.

   * [Eisenberg90] Michael Eisenberg, with William Clinger and Anne
     Hartheimer.  Harold Abelson, editor.  *Programming In MacScheme.*
     Scientific Press, San Francisco, 1990.

   * [Feeley86] Marc Feeley.  Deux approches `a l'implantation du
     language Scheme.  M.Sc. thesis, D'epartement d'Informatique et de
     Recherche   Op'erationelle, University of Montreal, May 1986.

   * [Feeley87] Marc Feeley and Guy LaPalme.  Using closures for code
     generation.  *Journal of Computer Languages* 12(1):47-66, 1987.

   * [Feeley90] Marc Feeley and James Miller.  A parallel virtual
     machine for efficient Scheme compilation.  In *Proceedings of the
     1990 ACM Conference on Lisp and   Functional Programming*, June
     1990.

   * [Felleisen87b] Matthias Felleisen.  Reflections on Landin's
     J-Operator: a partly historical note.  *Journal of Computer
     Languages* 12(3/4):197-207, 1987.

   * [Felleisen86b] Matthias Felleisen and Daniel P. Friedman.  Control
     operators, the SECD-machine, and the lambda-calculus.  In *3rd
     Working Conference on the Formal Description of    Programming
     Concepts*, pages 193-219, August 1986.

   * [Felleisen86c] Matthias Felleisen and Daniel P. Friedman.  A
     closer look at export and import statements.  *Journal of Computer
     Languages* 11(1):29-37, 1986.

   * [Felleisen87] Matthias Felleisen and Daniel P. Friedman.  A
     calculus for assignments in higher-order languages.  In
     *Conference Record of the 14th Annual ACM Symposium   on
     Principles of Programming Languages*, pages 314-345, January 1987.

   * [Felleisen87d] Matthias Felleisen and Daniel P. Friedman.  A
     reduction semantics for imperative higher-order languages.  In
     *Lecture Notes in Computer Science*, *Parallel Architectures and
     Languages Europe* 259:206-223, 1987.  De Bakker, Nijman and
     Treleaven, editors.  Springer-Verlag, Berlin.

   * [Felleisen86] Matthias Felleisen, Daniel P. Friedman, Eugene
     Kohlbecker, and Bruce Duba.  Reasoning with continuations.  In
     *Proceedings of the Symposium on Logic in Computer Science*,
     pages 131-141.  IEEE Computer Society Press, Washington DC, 1986.

   * [Felleisen87c] Matthias Felleisen, Daniel P. Friedman, Eugene E.
     Kohlbecker, and Bruce Duba.  A syntactic theory of sequential
     control.  *Theoretical Computer Science* 52:205-237, 1987.

   * [Felleisen88] Matthias Felleisen, Mitchell Wand, Daniel P.
     Friedman, and Bruce Duba.  Abstract continuations: a mathematical
     semantics for   handling functional jumps.  In *Proceedings of the
     1988 ACM Symposium on Lisp and   Functional Programming*,

     July 1988.

   * [Scheme311] Carol Fessenden, William Clinger, Daniel P. Friedman,
     and Christopher Haynes.  Scheme 311 version 4 reference manual.
     Indiana University Computer Science Technical Report 137, February
     1983.  Superseded by [Scheme84].

   * [Franco90] John Franco and Daniel P. Friedman.  Towards a facility
     for lexically scoped, dynamic mutual recursion   in Scheme.
     *Journal of Computer Languages* 15(1):55-64, 1990.

   * [Lisper] Daniel P. Friedman and Matthias Felleisen.  *The Little
     LISPer.* Science Research Associates, second edition 1986.

   * [littlelisper] Daniel P. Friedman and Matthias Felleisen.  *The
     Little LISPer.* MIT Press, 1987.

   * [Friedman85] Daniel P. Friedman and Christopher T. Haynes.
     Constraining control.  In *Proceedings of the Twelfth Annual
     Symposium on Principles of   Programming Languages*, pages 245-254.
     ACM, January 1985.

   * [Friedman84] Daniel P. Friedman, Christopher T. Haynes, and Eugene
     Kohlbecker.  Programming with continuations.  In *Program
     Transformation and Programming Environments,*   pages 263-274.  P.
     Pepper, editor.  Springer-Verlag, 1984.

   * [Scheme84] D. Friedman, C. Haynes, E. Kohlbecker, and M. Wand.
     Scheme 84 interim reference manual.  Indiana University Computer
     Science Technical Report 153, January 1985.

   * [Friedman84b] Daniel P. Friedman and Mitchell Wand.  Reification:
     reflection without metaphysics.  In *Conference Record of the 1984
     ACM Symposium on Lisp   and Functional Programming*, pages 348-355.

   * [Haynes86] Christopher T. Haynes.  Logic continuations.  In
     *Proceedings of the Third International Conference on   Logic
     Programming,* pages 671-685.  Springer-Verlag, July 1986.

   * [Engines] Christopher T. Haynes and Daniel P. Friedman.  Engines
     build process abstractions.  In *Conference Record of the 1984 ACM
     Symposium on Lisp and   Functional Programming,* pages 18-24.

   * [Haynes87b] Christopher T. Haynes and Daniel P. Friedman.
     Abstracting timed preemption with engines.  *Journal of Computer
     Languages* 12(2):109-121, 1987.

   * [Haynes87a] Christopher T. Haynes and Daniel P. Friedman.
     Embedding continuations in procedural objects.  *ACM Transactions
     on Programming Languages and Systems* 9(4):582-598,   October 1987.

   * [Haynes86] Christopher T. Haynes and Daniel P. Friedman and
     Mitchell Wand.  Obtaining coroutines with continuations.  *Journal
     of Computer Languages* 11(3/4):143-153, 1986.

   * [Henderson82] Peter Henderson.  Functional geometry.  In
     *Conference Record of the 1982 ACM Symposium on Lisp and
     Functional Programming*, pages 179-187.

   * [Dybvig88] Robert Hieb, R. Kent Dybvig, and Carl Bruggeman.
     Representing control in the presence of first-class continuations.
     In *Proceedings of the ACM SIGPLAN '90 Conference on Programming
     Language Design and Implementation*, pages 66-77, June 1990.
     Proceedings published as *SIGPLAN Notices* 25(6), June 1990.

   * [IEEE] *IEEE Standard 754-1985.  IEEE Standard for Binary
     Floating-Point Arithmetic.*  IEEE, New York, 1985.

   * [IEEEScheme] *IEEE Standard 1178-1990.  IEEE Standard for the
     Scheme   Programming Language.*  IEEE, New York, 1991.

   * [Kohlbecker86] Eugene Edmund Kohlbecker Jr.  *Syntactic Extensions
     in the Programming Language Lisp.* PhD thesis, Indiana University,
     August 1986.

   * [hygienic] Eugene E. Kohlbecker, Daniel P. Friedman, Matthias
     Felleisen, and Bruce Duba.  Hygienic macro expansion.  In
     *Proceedings of the 1986 ACM Conference on Lisp   and Functional
     Programming*, pages 151-161.

   * [Kranz86] David Kranz, Richard Kelsey, Jonathan Rees, Paul Hudak,
     James Philbin,   and Norman Adams.  Orbit: An optimizing compiler
     for Scheme.  In *Proceedings of the SIGPLAN '86 Symposium on
     Compiler   Construction*, pages 219-233.  ACM, June 1986.
     Proceedings published as *SIGPLAN Notices* 21(7), July 1986.

   * [Kranz88] David Kranz.  *Orbit: An optimizing compiler for Scheme.*
     PhD thesis, Yale University, 1988.

   * [Landin65] Peter Landin.  A correspondence between Algol 60 and
     Church's lambda notation: Part I.  *Communications of the ACM*
     8(2):89-101, February 1965.

   * [McDermott80] Drew McDermott.  An efficient environment allocation
     scheme in an interpreter for a   lexically-scoped lisp.  In
     *Conference Record of the 1980 Lisp Conference,* pages   154-162.
     Proceedings reprinted by ACM.

   * [MITScheme] MIT Department of Electrical Engineering and Computer
     Science.  Scheme manual, seventh edition.  September 1984.

   * [Muchnick80] Steven S. Muchnick and Uwe F. Pleban.  A semantic
     comparison of Lisp and Scheme.  In *Conference Record of the 1980
     Lisp Conference*, pages 56-64.  Proceedings reprinted by ACM.

   * [Naur63] Peter Naur et al.  Revised report on the algorithmic
     language Algol 60.  *Communications of the ACM* 6(1):1-17, January
     1963.

   * [Penfield81] Paul Penfield, Jr.  Principal values and branch cuts
     in complex APL.  In *APL '81 Conference Proceedings,* pages
     248-256.  ACM SIGAPL, San Francisco, September 1981.  Proceedings
     published as *APL Quote Quad* 12(1), ACM, September 1981.

   * [Pitman85] Kent M. Pitman.  Exceptional situations in Lisp.  MIT
     Artificial Intelligence Laboratory Working Paper 268, February
     1985.

   * [Pitman83] Kent M. Pitman.  The revised MacLisp manual (Saturday
     evening edition).  MIT Laboratory for Computer Science Technical
     Report 295, May 1983.

   * [Pitman80] Kent M. Pitman.  Special forms in Lisp.  In *Conference
     Record of the 1980 Lisp Conference*, pages 179-187.  Proceedings
     reprinted by ACM.

   * [Plebanthesis] Uwe F. Pleban.  *A Denotational Approach to Flow
     Analysis and Optimization of Scheme, A Dialect of Lisp.* PhD
     thesis, University of Kansas, 1980.

   * [Rees89] Jonathan A. Rees.  *Modular Macros*.  M.S. thesis, MIT,
     May 1989.

   * [Rees82] Jonathan A. Rees and Norman I. Adams IV.  T: A dialect of
     Lisp or, lambda: The ultimate software tool.  In *Conference
     Record of the 1982 ACM Symposium on Lisp and   Functional
     Programming*, pages 114-122.

   * [Rees84] Jonathan A. Rees, Norman I. Adams IV, and James R. Meehan.
     The T manual, fourth edition.  Yale University Computer Science
     Department, January 1984.

   * [R3RS] Jonathan Rees and William Clinger, editors.  The revised^3
     report on the algorithmic language Scheme.  In *ACM SIGPLAN
     Notices* 21(12), pages 37-79, December 1986.

   * [Reynolds72] John Reynolds.  Definitional interpreters for higher
     order programming languages.  In *ACM Conference Proceedings*,
     pages 717-740.  ACM,  1972.

   * [Rozas84] Guillermo J. Rozas.  Liar, an Algol-like compiler for
     Scheme.  S. B. thesis, MIT Department of Electrical Engineering
     and Computer   Science, January 1984.

   * [schflow] Olin Shivers.  Control flow analysis in Scheme.
     *Proceedings of the SIGPLAN 1988 Conference on   Programming
     Language Design and Implementation*, pages 164-174.  Proceedings
     published as *SIGPLAN Notices* 23(7), July 1988.

   * [Sitaram90] Dorai Sitaram and Matthias Felleisen.  Control
     delimiters and their hierarchies.  *Lisp and Symbolic Computation*
     3(1):67-99, January 1990.

   * [Smith84] Brian C. Smith.  Reflection and semantics in a
     procedural language.  MIT Laboratory for Computer Science
     Technical Report 272, January 1982.

   * [Springer89] George Springer and Daniel P. Friedman.  *Scheme and
     the Art of Programming.* MIT Press and McGraw-Hill, 1989.

   * [Srivastava85] Amitabh Srivastava, Don Oxley, and Aditya
     Srivastava.  An(other) integration of logic and functional
     programming.  In *Proceedings of the Symposium on Logic
     Programming*, pages 254-260.  IEEE, 1985.

   * [Stallman80] Richard M. Stallman.  Phantom stacks--if you look too
     hard, they aren't there.  MIT Artificial Intelligence Memo 556,
     July 1980.

   * [Declarative] Guy Lewis Steele Jr.  Lambda, the ultimate
     declarative.  MIT Artificial Intelligence Memo 379, November 1976.

   * [Debunking] Guy Lewis Steele Jr.  Debunking the "expensive
     procedure call" myth, or procedure call   implementations
     considered harmful, or lambda, the ultimate GOTO.  In *ACM
     Conference Proceedings*, pages 153-162.  ACM, 1977.

   * [Macaroni] Guy Lewis Steele Jr.  Macaroni is better than spaghetti.
     In *Proceedings of the Symposium on Artificial Intelligence and
     Programming Languages*, pages 60-66.  These proceedings were
     published as a special joint issue of *SIGPLAN Notices* 12(8) and
     *SIGART Newsletter* 64, August 1977.

   * [Rabbit] Guy Lewis Steele Jr.  Rabbit: a compiler for Scheme.  MIT
     Artificial Intelligence Laboratory Technical Report 474, May 1978.

   * [renamegoto] Guy Lewis Steele Jr.  Compiler optimization based on
     viewing LAMBDA as RENAME + GOTO.  In *AI: An MIT Perspective.*
     Patrick Henry Winston Richard Henry Brown, editor.  MIT Press,
     1980.

   * [CLoverview] Guy Lewis Steele Jr.  An overview of Common Lisp.  In
     *Conference Record of the 1982 ACM Symposium on Lisp and
     Functional Programming*, pages 98-107.

   * [CLtL] Guy Lewis Steele Jr.  *Common Lisp: The Language.* Digital
     Press, Burlington MA, 1984.

   * [Imperative] Guy Lewis Steele Jr. and Gerald Jay Sussman.  Lambda,
     the ultimate imperative.  MIT Artificial Intelligence Memo 353,
     March 1976.

   * [Scheme78] Guy Lewis Steele Jr. and Gerald Jay Sussman.  The
     revised report on Scheme, a dialect of Lisp.  MIT Artificial
     Intelligence Memo 452, January 1978.

   * [TAOTI] Guy Lewis Steele Jr. and Gerald Jay Sussman.  The art of
     the interpreter, or the modularity complex (parts zero, one,   and
     two).  MIT Artificial Intelligence Memo 453, May 1978.

   * [DOALBP] Guy Lewis Steele Jr. and Gerald Jay Sussman.  Design of a
     Lisp-based processor.  *Communications of the ACM* 23(11):628-645,
     November 1980.

   * [Dream] Guy Lewis Steele Jr. and Gerald Jay Sussman.  The dream of
     a lifetime: a lazy variable extent mechanism.  In *Conference
     Record of the 1980 Lisp Conference*, pages 163-172.  Proceedings
     reprinted by ACM.

   * [howtoprint] Guy Lewis Steele Jr. and Jon L White.  How to print
     floating point numbers accurately.  In *Proceedings of the ACM
     SIGPLAN '90 Conference   on Programming Language Design and
     Implementation*, pages 112-126.  Proceedings published as *SIGPLAN
     Notices* 25(6), June 1990.

   * [Sussman82] Gerald Jay Sussman.  Lisp, programming and
     implementation.  In *Functional Programming and its Applications.*
     Darlington, Henderson, Turner, editor.  Cambridge University
     Press, 1982.

   * [Scheme75] Gerald Jay Sussman and Guy Lewis Steele Jr.  Scheme: an
     interpreter for extended lambda calculus.  MIT Artificial
     Intelligence Memo 349, December 1975.

   * [Scheme79] Gerald Jay Sussman, Jack Holloway, Guy Lewis Steele
     Jr., and Alan Bell.  Scheme-79--Lisp on a chip.  *IEEE Computer*
     14(7):10-21, July 1981.

   * [Stoy77] Joseph E. Stoy.  *Denotational Semantics: The
     Scott-Strachey Approach to   Programming Language Theory.* MIT
     Press, Cambridge, 1977.

   * [TI85] Texas Instruments, Inc.  *TI Scheme Language Reference
     Manual.* Preliminary version 1.0, November 1985.

   * [Vegdahl89] Steven R. Vegdahl and Uwe F. Pleban.  The runtime
     environment for Screme, a Scheme implementation on the 88000.  In
     *Proceedings of the Third International Conference on Architectural
      Support for Programming Languages and Operating Systems*,
     pages 172-182, April 1989.

   * [Wand78] Mitchell Wand.  Continuation-based program transformation
     strategies.  *Journal of the ACM* 27(1):174-180, 1978.

   * [Wand80] Mitchell Wand.  Continuation-based multiprocessing.  In
     *Conference Record of the 1980 Lisp Conference*, pages 19-28.
     Proceedings available from ACM.

   * [Wand86] Mitchell Wand.  *Finding the source of type errors.* In
     *Conference Record of the Thirteenth Annual Symposium on
     Principles of Programming Languages*, pages 38-43, 1986.

   * [tower] Mitchell Wand.  The mystery of the tower revealed: a
     non-reflective description of the reflective tower.  In
     *Proceedings of the 1986 ACM Symposium on LISP and Functional
     Programming*, pages 298-307, August 1986.

   * [Wand78] Mitchell Wand and Daniel P. Friedman.  Compiling lambda
     expressions using continuations and factorizations.  *Journal of
     Computer Languages* 3:241-263, 1978.

   * [Wand88] Mitchell Wand and Daniel P. Friedman.  The mystery of the
     tower revealed: a non-reflective description of the   reflective
     tower.  In *Meta-Level Architectures and Reflection*, pages
     111-134.  P. Maes and D. Nardi, editor.  Elsevier Sci. Publishers
     B.V. (North Holland), 1988.