2 November 1991

Ports
-----

Ports represent input and output devices.  To Scheme, an input port is a
Scheme object that can deliver characters upon command, while an output
port is a Scheme object that can accept characters.

 - essential procedure: call-with-input-file STRING PROC
 - essential procedure: call-with-output-file STRING PROC
     PROC should be a procedure of one argument, and STRING should be a
     string naming a file.  For `call-with-input-file', the file must
     already exist; for `call-with-output-file', the effect is
     unspecified if the file already exists. These procedures call PROC
     with one argument: the port obtained by opening the named file for
     input or output.  If the file cannot be opened, an error is
     signalled.  If the procedure returns, then the port is closed
     automatically and the value yielded by the procedure is returned.
     If the procedure does not return, then the port will not be closed
     automatically unless it is possible to prove that the port will
     never again be used for a read or write operation.

          *Rationale:* Because Scheme's escape procedures have
          unlimited extent, it  is possible to escape from the current
          continuation but later to escape back in.  If implementations
          were permitted to close the port on any escape from the
          current continuation, then it would be impossible to write
          portable code using both `call-with-current-continuation' and
          `call-with-input-file' or `call-with-output-file'.

 - essential procedure: input-port? OBJ
 - essential procedure: output-port? OBJ
     Returns #t if OBJ is an input port or output port respectively,
     otherwise returns #f.

 - essential procedure: current-input-port
 - essential procedure: current-output-port
     Returns the current default input or output port.

 - procedure: with-input-from-file STRING THUNK
 - procedure: with-output-to-file STRING THUNK
     THUNK must be a procedure of no arguments, and STRING must be a
     string naming a file.  For `with-input-from-file', the file must
     already exist; for `with-output-to-file', the effect is
     unspecified if the file already exists. The file is opened for
     input or output, an input or output port connected to it is made
     the default value returned by `current-input-port' or
     `current-output-port', and the THUNK is called with no arguments.
     When the THUNK returns, the port is closed and the previous
     default is restored.  `With-input-from-file' and
     `with-output-to-file' return the value yielded by THUNK.  If an
     escape procedure is used to escape from the continuation of these
     procedures, their behavior is implementation dependent.

 - essential procedure: open-input-file FILENAME
     Takes a string naming an existing file and returns an input port
     capable of delivering characters from the file.  If the file
     cannot be opened, an error is signalled.

 - essential procedure: open-output-file FILENAME
     Takes a string naming an output file to be created and returns an
     output port capable of writing characters to a new file by that
     name.  If the file cannot be opened, an error is signalled.  If a
     file with the given name already exists, the effect is unspecified.

 - essential procedure: close-input-port PORT
 - essential procedure: close-output-port PORT
     Closes the file associated with PORT, rendering the PORT incapable
     of delivering or accepting characters.

     These routines have no effect if the file has already been closed.
     The value returned is unspecified.

Input
-----

 - essential procedure: read
 - essential procedure: read PORT
     `Read' converts external representations of Scheme objects into the
     objects themselves.  That is, it is a parser for the nonterminal
     <datum> (see sections External representation. and
     Pairs and lists.).  `Read' returns the next object parsable from
     the given input PORT, updating PORT to point to the first
     character past the end of the external representation of the
     object.

     If an end of file is encountered in the input before any
     characters are found that can begin an object, then an end of file
     object is returned.   The port remains open, and further attempts
     to read will also return an end of file object.  If an end of file
     is encountered after the beginning of an object's external
     representation, but the external representation is incomplete and
     therefore not parsable, an error is signalled.

     The PORT argument may be omitted, in which case it defaults to the
     value returned by `current-input-port'.  It is an error to read
     from a closed port.

 - essential procedure: read-char
 - essential procedure: read-char PORT
     Returns the next character available from the input PORT, updating
     the PORT to point to the following character.  If no more
     characters are available, an end of file object is returned.  PORT
     may be omitted, in which case it defaults to the value returned by
     `current-input-port'.

 - essential procedure: peek-char
 - essential procedure: peek-char PORT
     Returns the next character available from the input PORT,
     *without* updating the PORT to point to the following character.
     If no more characters are available, an end of file object is
     returned.  PORT may be omitted, in which case it defaults to the
     value returned by `current-input-port'.

          *Note:* The value returned by a call to `peek-char' is the
          same as the value that would have been returned by a call to
          `read-char' with the same PORT.  The only difference is that
          the very next call to `read-char' or `peek-char' on that PORT
          will return the value returned by the preceding call to
          `peek-char'.  In particular, a call to `peek-char' on an
          interactive port will hang waiting for input whenever a call
          to `read-char' would have hung.

 - essential procedure: eof-object? OBJ
     Returns #t if OBJ is an end of file object, otherwise returns #f.
     The precise set of end of file objects will vary among
     implementations, but in any case no end of file object will ever
     be an object that can be read in using `read'.

 - procedure: char-ready?
 - procedure: char-ready? PORT
     Returns #t if a character is ready on the input PORT and returns
     #f otherwise.  If `char-ready' returns #t then the next
     `read-char' operation on the given PORT is guaranteed not to hang.
     If the PORT is at end of file then `char-ready?' returns #t.
     PORT may be omitted, in which case it defaults to the value
     returned by `current-input-port'.

          *Rationale:* `Char-ready?' exists to make it possible for a
          program to accept characters from interactive ports without
          getting stuck waiting for input.  Any input editors
          associated with such ports must ensure that characters whose
          existence has been asserted by `char-ready?' cannot be rubbed
          out.  If `char-ready?' were to return #f at end of file, a
          port at end of file would be indistinguishable from an
          interactive port that has no ready characters.

Output
------

 - essential procedure: write OBJ
 - essential procedure: write OBJ PORT
     Writes a written representation of OBJ to the given PORT.  Strings
     that appear in the written representation are enclosed in
     doublequotes, and within those strings backslash and doublequote
     characters are escaped by backslashes.  `Write' returns an
     unspecified value.  The PORT argument may be omitted, in which
     case it defaults to the value returned by `current-output-port'.

 - essential procedure: display OBJ
 - essential procedure: display OBJ PORT
     Writes a representation of OBJ to the given PORT.  Strings that
     appear in the written representation are not enclosed in
     doublequotes, and no characters are escaped within those strings.
     Character objects appear in the representation as if written by
     `write-char' instead of by `write'.  `Display' returns an
     unspecified value.  The PORT argument may be omitted, in which
     case it defaults to the value returned by `current-output-port'.

          *Rationale:* `Write' is intended for producing
          machine-readable output and `display' is for producing
          human-readable output.  Implementations that allow
          "slashification" within symbols will probably want `write'
          but not `display' to slashify funny characters in symbols.

 - essential procedure: newline
 - essential procedure: newline PORT
     Writes an end of line to PORT.  Exactly how this is done differs
     from one operating system to another.  Returns an unspecified
     value.  The PORT argument may be omitted, in which case it
     defaults to the value returned by `current-output-port'.

 - essential procedure: write-char CHAR
 - essential procedure: write-char CHAR PORT
     Writes the character CHAR (not an external representation of the
     character) to the given PORT and returns an unspecified value.  The
     PORT argument may be omitted, in which case it defaults to the
     value returned by `current-output-port'.

System interface
----------------

Questions of system interface generally fall outside of the domain of
this report.  However, the following operations are important enough to
deserve description here.

 - essential procedure: load FILENAME
     FILENAME should be a string naming an existing file containing
     Scheme source code. The `load' procedure reads expressions and
     definitions from the file and evaluates them sequentially.  It is
     unspecified whether the results of the expressions are printed.
     The `load' procedure does not affect the values returned by
     `current-input-port' and `current-output-port'.  `Load' returns an
     unspecified value.

          *Rationale:* For portability, `load' must operate on source
          files.  Its operation on other kinds of files necessarily
          varies among implementations.

 - procedure: transcript-on FILENAME
 - procedure: transcript-off
     FILENAME must be a string naming an output file to be created. The
     effect of `transcript-on' is to open the named file for output,
     and to cause a transcript of subsequent interaction between the
     user and the Scheme system to be written to the file.  The
     transcript is ended by a call to `transcript-off', which closes the
     transcript file.  Only one transcript may be in progress at any
     time, though some implementations may relax this restriction.  The
     values returned by these procedures are unspecified.

Formal syntax and semantics
***************************

This chapter provides formal descriptions of what has already been
described informally in previous chapters of this report.

Formal syntax
=============

This section provides a formal syntax for Scheme written in an extended
BNF.  The syntax for the entire language, including features which are
not essential, is given here.

All spaces in the grammar are for legibility.  Case is insignificant;
for example, `#x1A' and `#X1a' are equivalent.  <empty> stands for the
empty string.

The following extensions to BNF are used to make the description more
concise:  <thing>* means zero or more occurrences of <thing>; and
<thing>+ means at least one <thing>.

Lexical structure
-----------------

This section describes how individual tokens (identifiers, numbers,
etc.) are formed from sequences of characters.  The following sections
describe how expressions and programs are formed from sequences of
tokens.

<Intertoken space> may occur on either side of any token, but not
within a token.

Tokens which require implicit termination (identifiers, numbers,
characters, and dot) may be terminated by any <delimiter>, but not
necessarily by anything else.

<token> --> <identifier> | <boolean> | <number>
     | <character> | <string>
     | ( | ) | #( | ' | ` | , | ,@ | .
<delimiter> --> <whitespace> | ( | ) | " | ;
<whitespace> --> <space or newline>
<comment> --> ;  <all subsequent characters up to a
                 line break>
<atmosphere> --> <whitespace> | <comment>
<intertoken space> --> <atmosphere>*

<identifier> --> <initial> <subsequent>*
     | <peculiar identifier>
<initial> --> <letter> | <special initial>
<letter> --> a | b | c | ... | z
<special initial> --> ! | $ | % | & | * | / | : | < | =
     | > | ? | ~ | _ | ^
<subsequent> --> <initial> | <digit>
     | <special subsequent>
<digit> --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
<special subsequent> --> . | + | -
<peculiar identifier> --> + | - | ...
<syntactic keyword> --> <expression keyword>
     | else | => | define
     | unquote | unquote-splicing
<expression keyword> --> quote | lambda | if
     | set! | begin | cond | and | or | case
     | let | let* | letrec | do | delay
     | quasiquote

`<variable> => <'any <identifier> that isn't
                also a <syntactic keyword>>

<boolean> --> #t | #f
<character> --> #\ <any character>
     | #\ <character name>
<character name> --> space | newline

<string> --> " <string element>* "
<string element> --> <any character other than " or \>
     | \" | \\

<number> --> <num 2>| <num 8>
     | <num 10>| <num 16>

The following rules for <num R>, <complex R>, <real R>, <ureal R>,
<uinteger R>, and <prefix R> should be replicated for R = 2, 8, 10, and
16.  There are no rules for <decimal 2>, <decimal 8>, and <decimal 16>,
which means that numbers containing decimal points or exponents must be
in decimal radix.

<num R> --> <prefix R> <complex R>
<complex R> --> <real R> | <real R> @ <real R>
    | <real R> + <ureal R> i | <real R> - <ureal R> i
    | <real R> + i | <real R> - i
    | + <ureal R> i | - <ureal R> i | + i | - i
<real R> --> <sign> <ureal R>
<ureal R> --> <uinteger R>
    | <uinteger R> / <uinteger R>
    | <decimal R>
<decimal 10> --> <uinteger 10> <suffix>
    | . <digit 10>+ #* <suffix>
    | <digit 10>+ . <digit 10>* #* <suffix>
    | <digit 10>+ #+ . #* <suffix>
<uinteger R> --> <digit R>+ #*
<prefix R> --> <radix R> <exactness>
    | <exactness> <radix R>

<suffix> --> <empty>
    | <exponent marker> <sign> <digit 10>+
<exponent marker> --> e | s | f | d | l
<sign> --> <empty>  | + |  -
<exactness> --> <empty> | #i | #e
<radix 2> --> #b
<radix 8> --> #o
<radix 10> --> <empty> | #d
<radix 16> --> #x
<digit 2> --> 0 | 1
<digit 8> --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
<digit 10> --> <digit>
<digit 16> --> <digit 10> | a | b | c | d | e | f

External representations
------------------------

<Datum> is what the `read' procedure (section Input.)
successfully parses.  Note that any string that parses as an
<expression> will also parse as a <datum>.

<datum> --> <simple datum> | <compound datum>
<simple datum> --> <boolean> | <number>
     | <character> | <string> |  <symbol>
<symbol> --> <identifier>
<compound datum> --> <list> | <vector>
<list> --> (<datum>*) | (<datum>+ . <datum>)
       | <abbreviation>
<abbreviation> --> <abbrev prefix> <datum>
<abbrev prefix> --> ' | ` | , | ,@
<vector> --> #(<datum>*)

Expressions
-----------

<expression> --> <variable>
     | <literal>
     | <procedure call>
     | <lambda expression>
     | <conditional>
     | <assignment>
     | <derived expression>

<literal> --> <quotation> | <self-evaluating>
<self-evaluating> --> <boolean> | <number>
     | <character> | <string>
<quotation> --> '<datum> | (quote <datum>)
<procedure call> --> (<operator> <operand>*)
<operator> --> <expression>
<operand> --> <expression>

<lambda expression> --> (lambda <formals> <body>)
<formals> --> (<variable>*) | <variable>
     | (<variable>+ . <variable>)
<body> --> <definition>* <sequence>
<sequence> --> <command>* <expression>
<command> --> <expression>

<conditional> --> (if <test> <consequent> <alternate>)
<test> --> <expression>
<consequent> --> <expression>
<alternate> --> <expression> | <empty>

<assignment> --> (set! <variable> <expression>)

<derived expression> -->
       (cond <cond clause>+)
     | (cond <cond clause>* (else <sequence>))
     | (case <expression>
         <case clause>+)
     | (case <expression>
         <case clause>*
         (else <sequence>))
     | (and <test>*)
     | (or <test>*)
     | (let (<binding spec>*) <body>)
     | (let <variable> (<binding spec>*) <body>)
     | (let* (<binding spec>*) <body>)
     | (letrec (<binding spec>*) <body>)
     | (begin <sequence>)
     | (do (<iteration spec>*)
           (<test> <sequence>)
         <command>*)
     | (delay <expression>)
     | <quasiquotation>

<cond clause> --> (<test> <sequence>)
      | (<test>)
      | (<test> => <recipient>)
<recipient> --> <expression>
<case clause> --> ((<datum>*) <sequence>)

<binding spec> --> (<variable> <expression>)
<iteration spec> --> (<variable> <init> <step>)
    | (<variable> <init>)
<init> --> <expression>
<step> --> <expression>

Quasiquotations
---------------

The following grammar for quasiquote expressions is not context-free.
It is presented as a recipe for generating an infinite number of
production rules.  Imagine a copy of the following rules for D = 1,
2,3, ....  D keeps track of the nesting depth.

<quasiquotation> --> <quasiquotation 1>
<template 0> --> <expression>
<quasiquotation D> --> `<template D>
       | (quasiquote <template D>)
<template D> --> <simple datum>
       | <list template D>
       | <vector template D>
       | <unquotation D>
<list template D> --> (<template or splice D>*)
       | (<template or splice D>+ . <template D>)
       | '<template D>
       | <quasiquotation D+1>
<vector template D> --> #(<template or splice D>*)
<unquotation D> --> ,<template D-1>
       | (unquote <template D-1>)
<template or splice D> --> <template D>
       | <splicing unquotation D>
<splicing unquotation D> --> ,@<template D-1>
       | (unquote-splicing <template D-1>)

In <quasiquotation>s, a <list template D> can sometimes be confused
with either an <unquotation D> or a <splicing unquotation D>.  The
interpretation as an <unquotation> or <splicing unquotation D> takes
precedence.

Programs and definitions
------------------------

<program> --> <command or definition>*
<command or definition> --> <command> | <definition>
<definition> --> (define <variable> <expression>)
      | (define (<variable> <def formals>) <body>)
      | (begin <definition>*)
<def formals> --> <variable>*
      | <variable>+ . <variable>

Formal semantics
================

This section provides a formal denotational semantics for the primitive
expressions of Scheme and selected built-in procedures.  The concepts
and notation used here are described in [STOY77].

     *Note:* The formal semantics section was written in LaTeX which is
     incompatible with TeXinfo.  See the Formal semantics section of
     the original document from which this was derived.

Derived expression types
========================

This section gives rewrite rules for the derived expression types.  By
the application of these rules, any expression can be reduced to a
semantically equivalent expression in which only the primitive
expression types (literal, variable, call, `lambda', `if', `set!')
occur.

     (cond (<test> <sequence>)
           <clause2> ...,)
      ==   (if <test>
               (begin <sequence>)
               (cond <clause2> ...,))

     (cond (<test>)
           <clause2> ...,)
      ==   (or <test> (cond <clause2> ...,))

     (cond (<test> => <recipient>)
           <clause2> ...,)
      ==   (let ((test-result <test>)
                 (thunk2 (lambda () <recipient>))
                 (thunk3 (lambda () (cond <clause2> ...,))))
             (if test-result
                 ((thunk2) test-result)
                 (thunk3)))

     (cond (else <sequence>))
      ==   (begin <sequence>)

     (cond)
      ==   <some expression returning an unspecified value>

     (case <key>
       ((d1 ...,) <sequence>)
       ...,)
      ==   (let ((key <key>)
                 (thunk1 (lambda () <sequence>))
                 ...,)
             (cond ((<memv> key '(d1 ...,)) (thunk1))
                    ...,))

     (case <key>
       ((d1 ...,) <sequence>)
       ...,
       (else f1 f2 ...,))
      ==   (let ((key <key>)
                 (thunk1 (lambda () <sequence>))
                 ...,
                 (elsethunk (lambda () f1 f2 ...,)))
             (cond ((<memv> key '(d1 ...,)) (thunk1))
                    ...,
                   (else (elsethunk))))

where <memv> is an expression evaluating to the `memv' procedure.

     (and)          ==   #t
     (and <test>)   ==   <test>
     (and <test1> <test2> ...,)
      ==   (let ((x <test1>)
                 (thunk (lambda () (and <test2> ...,))))
             (if x (thunk) x))

     (or)           ==   #f
     (or <test>)    ==   <test>
     (or <test1> <test2> ...,)
      ==   (let ((x <test1>)
                 (thunk (lambda () (or <test2> ...,))))
             (if x x (thunk)))

     (let ((<variable1> <init1>) ...,)
       <body>)
      ==   ((lambda (<variable1> ...,) <body>) <init1> ...,)

     (let* () <body>)
      ==   ((lambda () <body>))
     (let* ((<variable1> <init1>)
            (<variable2> <init2>)
            ...,)
       <body>)
      ==   (let ((<variable1> <init1>))
             (let* ((<variable2> <init2>)
                    ...,)
               <body>))

     (letrec ((<variable1> <init1>)
              ...,)
       <body>)
      ==   (let ((<variable1> <undefined>)
                 ...,)
              (let ((<temp1> <init1>)
                    ...,)
                (set! <variable1> <temp1>)
                ...,)
              <body>)

where <temp1>, <temp2>, ..., are variables, distinct from <variable1>,
...,, that do not free occur in the original <init> expressions, and
<undefined> is an expression which returns something that when stored
in a location makes it an error to try to obtain the value stored in
the location.  (No such expression is defined, but one is assumed to
exist for the purposes of this rewrite rule.)  The second `let'
expression in the expansion is not strictly necessary, but it serves to
preserve the property that the <init> expressions are evaluated in an
arbitrary order.

     (begin <sequence>)
      ==   ((lambda () <sequence>))

The following alternative expansion for `begin' does not make use of
the ability to write more than one expression in the body of a lambda
expression.  In any case, note that these rules apply only if
<sequence> contains no definitions.

     (begin <expression>) ==   <expression>
     (begin <command> <sequence>)
      ==   ((lambda (ignore thunk) (thunk))
            <command>
            (lambda () (begin <sequence>)))

The following expansion for `do' is simplified by the assumption that
no <step> is omitted.  Any `do' expression in which a <step> is omitted
can be replaced by an equivalent `do' expression in which the
corresponding <variable> appears as the <step>.

     (do ((<variable1> <init1> <step1>)
          ...,)
         (<test> <sequence>)
       <command1> ...,)
      ==   (letrec ((<loop>
                     (lambda (<variable1> ...,)
                       (if <test>
                           (begin <sequence>)
                           (begin <command1>
                                  ...,
                                  (<loop> <step1> ...,))))))
             (<loop> <init1> ...,))

where <loop> is any variable which is distinct from <variable1>, ...,,
and which does not occur free in the `do' expression.

     (let <variable_0> ((<variable1> <init1>) ...,)
       <body>)
      ==   ((letrec ((<variable_0> (lambda (<variable1> ...,)
                                  <body>)))
               <variable_0>)
            <init1> ...,)

     (delay <expression>)
      ==   (<make-promise> (lambda () <expression>))

where <make-promise> is an expression evaluating to some procedure
which behaves appropriately with respect to the `force' procedure; see
section Control features.

Notes
*****

Language changes
================

This section enumerates the changes that have been made to Scheme since
the "Revised^3 report" [R3RS] was published.

   * Although implementations may extend Scheme, they must offer a
     syntactic mode that adds no reserved words and preempts no lexical
     conventions of Scheme.

   * Implementations may report violations of implementation
     restrictions.

   * It is no longer specified whether the empty list counts as true or
     as false in conditional expressions.  It should be noted that the
     IEEE standard for Scheme requires the empty list to count as true
     [IEEEScheme].

   * The sets defined by `boolean?', `pair?', `symbol?', `number?',
     `char?', `string?', `vector?', and `procedure?' are required to be
     disjoint.

   * The variables bound by a `lambda', `let', `letrec', and `do' must
     not contain duplicates.

   * Nested `begin' expressions containing definitions are treated as a
     sequence of definitions.

   * The `eqv?' procedure is no longer required to be true of any two
     empty strings or two empty vectors.

   * The syntax of numerical constants has been changed, and the
     exactness implied by each syntax has been specified.

   * The semantics of many numerical procedures have been clarified.

   * `Rationalize' has been restricted to two arguments and its
     specification clarified.

   * The `number->string' and `string->number' procedures have been
     changed.

   * `Integer->char' now requires an exact integer argument.

   * The specification of the `force' procedure has been weakened.  The
     previous specification was unimplementable.

   * Variables removed: `t', `nil'.

   * Procedures removed: `approximate', `last-pair'.

   * Procedures added: `list?', `peek-char'.

   * Syntaxes made essential: `case', `and', `or', `quasiquote'.

   * Procedures made essential:

     reverse        char-ci=?        make-string
     max            char-ci<?        string-set!
     min            char-ci>?        string-ci=?
     modulo         char-ci<=?       string-ci<?
     gcd            char-ci>=?       string-ci>?
     lcm            char-alphabetic? string-ci<=?
     floor          char-numeric?    string-ci>=?
     ceiling        char-whitespace? string-append
     truncate       char-lower-case? open-input-file
     round          char-upper-case? open-output-file
     number->string char-upcase      close-input-port
     string->number char-downcase    close-output-port

   * Procedures required to accept more general numbers of arguments:
     `append', `+', `*', `-' (one argument), `/' (one argument), `=',
     `<', `>', `<=', `>=', `map', `for-each'.

   * A macro facility has been added as an appendix to this report.

Example
*******

`Integrate-system' integrates the system

           y_k^^ = f_k(y_1, y_2, ..., y_n),    k = 1, ..., n

of differential equations with the method of Runge-Kutta.

The parameter system-derivative is a function that takes a system state
(a vector of values for the state variables y_1, ..., y_n) and produces
a system derivative (the values y_1^^, ...,y_n^^).  The parameter
initial-state provides an initial system state, and h is an initial
guess for the length of the integration step.

The value returned by `integrate-system' is an infinite stream of
system states.

     (define integrate-system
       (lambda (system-derivative initial-state h)
         (let ((next (runge-kutta-4 system-derivative h)))
           (letrec ((states
                     (cons initial-state
                           (delay (map-streams next
                                               states)))))
             states))))

`Runge-Kutta-4' takes a function, f, that produces a system derivative
from a system state.  `Runge-Kutta-4' produces a function that takes a
system state and produces a new system state.

     (define runge-kutta-4
       (lambda (f h)
         (let ((*h (scale-vector h))
               (*2 (scale-vector 2))
               (*1/2 (scale-vector (/ 1 2)))
               (*1/6 (scale-vector (/ 1 6))))
           (lambda (y)
             ;; y is a system state
             (let* ((k0 (*h (f y)))
                    (k1 (*h (f (add-vectors y (*1/2 k0)))))
                    (k2 (*h (f (add-vectors y (*1/2 k1)))))
                    (k3 (*h (f (add-vectors y k2)))))
               (add-vectors y
                 (*1/6 (add-vectors k0
                                    (*2 k1)
                                    (*2 k2)
                                    k3))))))))

     (define elementwise
       (lambda (f)
         (lambda vectors
           (generate-vector
             (vector-length (car vectors))
             (lambda (i)
               (apply f
                      (map (lambda (v) (vector-ref  v i))
                           vectors)))))))

     (define generate-vector
       (lambda (size proc)
         (let ((ans (make-vector size)))
           (letrec ((loop
                     (lambda (i)
                       (cond ((= i size) ans)
                             (else
                              (vector-set! ans i (proc i))
                              (loop (+ i 1)))))))
             (loop 0)))))

     (define add-vectors (elementwise +))

     (define scale-vector
       (lambda (s)
         (elementwise (lambda (x) (* x s)))))

`Map-streams' is analogous to `map': it applies its first argument (a
procedure) to all the elements of its second argument (a stream).

     (define map-streams
       (lambda (f s)
         (cons (f (head s))
               (delay (map-streams f (tail s))))))

Infinite streams are implemented as pairs whose car holds the first
element of the stream and whose cdr holds a promise to deliver the rest
of the stream.

     (define head car)
     (define tail
       (lambda (stream) (force (cdr stream))))

The following illustrates the use of `integrate-system' in integrating
the system

                     C dv_C / dt = -i_L - v_C / R

                           L di_L / dt = v_C

which models a damped oscillator.

     (define damped-oscillator
       (lambda (R L C)
         (lambda (state)
           (let ((Vc (vector-ref state 0))
                 (Il (vector-ref state 1)))
             (vector (- 0 (+ (/ Vc (* R C)) (/ Il C)))
                     (/ Vc L))))))

     (define the-states
       (integrate-system
          (damped-oscillator 10000 1000 .001)
          '#(1 0)
          .01))

Appendix: Macros
****************

This appendix describes an extension to Scheme that allows programs to
define and use new derived expression types.  A derived expression type
that has been defined using this extension is called a *macro*.

Derived expression types introduced using this extension have the syntax

     (<keyword> <datum>*)

where <keyword> is an identifier that uniquely determines the
expression type.  This identifier is called the *syntactic keyword*, or
simply *keyword*, of the macro.  The number of the <datum>s, and their
syntax, depends on the expression type.

Each instance of a macro is called a *use* of the macro.  The set of
rules, or more generally the procedure, that specifies how a use of a
macro is transcribed into a more primitive expression is called the
*transformer* of the macro.

The extension described here consists of three parts:

   * A set of expressions used to establish that certain identifiers
     are macro keywords, associate them with macro transformers, and
     control the scope within which a macro is defined,

   * a convenient pattern language that makes it easy to write
     transformers for most macros, and

   * a compatible low-level macro facility for writing macro
     transformers that cannot be expressed by the pattern language.

With this extension, there are no reserved identifiers.  The syntactic
keyword of a macro may shadow variable bindings, and local variable
bindings may shadow keyword bindings.   All macros defined using the
pattern language are "hygienic" and "referentially transparent":

   * If a macro transformer inserts a binding for an identifier
     (variable or keyword), the identifier will in effect be renamed
     throughout its scope to avoid conflicts with other identifiers.

   * If a macro transformer inserts a free reference to an identifier,
     the reference refers to the binding that was visible where the
     transformer was specified, regardless of any local bindings that
     may surround the use of the macro.

This appendix is divided into three major sections.  The first section
describes the expressions and definitions used to introduce macros,
i.e. to bind identifiers to macro transformers.

The second section describes the pattern language.  This pattern
language is sufficient to specify most macro transformers, including
those for all the derived expression types from section Derived expression types.
The primary limitation of the pattern language is
that it is thoroughly hygienic, and thus cannot express macros that
bind identifiers implicitly.

The third section describes a low-level macro facility that could be
used to implement the pattern language described in the second section.
This low-level facility is also capable of expressing non-hygienic
macros and other macros whose transformers cannot be described by the
pattern language, and is important as an example of a more powerful
facility that can co-exist with the high-level pattern language.

The particular low-level facility described in the third section is but
one of several low-level facilities that have been designed and
implemented to complement the pattern language described in the second
section.  The design of such low-level macro facilities remains an
active area of research, and descriptions of alternative low-level
facilities will be published in subsequent documents.

Binding syntactic keywords
==========================

`Define-syntax', `let-syntax', and `letrec-syntax' are analogous to
`define', `let', and `letrec', but they bind syntactic keywords to
macro transformers instead of binding variables to locations that
contain values.  Furthermore, there is no `define-syntax' analogue of
the internal definitions described in section Internal definitions.

     *Rationale:* As discussed below, the syntax and scope rules for
     definitions give rise to syntactic ambiguities when syntactic
     keywords are not reserved.  Further ambiguities would arise if
     `define-syntax' were permitted at the beginning of a <body>, with
     scope rules analogous to those for internal definitions.

These new expression types and the pattern language described in
section Pattern language are added to Scheme by augmenting the
BNF in section Formal syntax with the following new
productions.  Note that the identifier `...' used in some of these
productions is not a metasymbol.

<expression> --> <macro use>
     | <macro block>

<macro use> --> (<keyword> <datum>*)
<keyword> --> <identifier>

<macro block> -->
       (let-syntax (<syntax spec>*) <body>)
     | (letrec-syntax (<syntax spec>*) <body>)
<syntax spec> --> (<keyword> <transformer spec>)
<transformer spec> -->
       (syntax-rules (<identifier>*) <syntax rule>*)
<syntax rule> --> (<pattern> <template>)
<pattern> --> <pattern identifier>
     | (<pattern>*)
     | (<pattern>+ . <pattern>)
     | (<pattern>* <pattern> <ellipsis>)
     | <pattern datum>
<pattern datum> --> <vector>
     | <string>
     | <character>
     | <boolean>
     | <number>
<template> --> <pattern identifier>
     | (<template element>*)
     | (<template element>+ . <template>)
     | <template datum>
<template element> --> <template>
     | <template> <ellipsis>
<template datum> --> <pattern datum>
<pattern identifier> --> <any identifier except `...'>
<ellipsis> --> <the identifier `...'>

<command or definition> --> <syntax definition>
<syntax definition> -->
       (define-syntax <keyword> <transformer spec>)
     | (begin <syntax definition>*)

Although macros may expand into definitions in any context that permits
definitions, it is an error for a definition to shadow a syntactic
keyword whose meaning is needed to determine whether some definition in
the group of top-level or internal definitions that contains the
shadowing definition is in fact a definition, or is needed to determine
the boundary between the group and the expressions that follow the
group.  For example, the following are errors:

     (define define 3)

     (begin (define begin list))

     (let-syntax
       ((foo (syntax-rules ()
               ((foo (proc args ...) body ...)
                (define proc
                  (lambda (args ...)
                    body ...))))))
       (let ((x 3))
         (foo (plus x y) (+ x y))
         (define foo x)
         (plus foo x)))

 - syntax: let-syntax <bindings> <body>
     *Syntax:* <Bindings> should have the form

     ((<keyword> <transformer spec>) ...,)

     Each <keyword> is an identifier, each <transformer spec> is an
     instance of `syntax-rules', and <body> should be a sequence of one
     or more expressions.  It is an error for a <keyword> to appear
     more than once in the list of keywords being bound.

     *Semantics:* The <body> is expanded in the syntactic environment
     obtained by extending the syntactic environment of the
     `let-syntax' expression with macros whose keywords are the
     <keyword>s, bound to the specified transformers.  Each binding of
     a <keyword> has <body> as its region.

     (let-syntax ((when (syntax-rules ()
                          ((when test stmt1 stmt2 ...)
                           (if test
                               (begin stmt1
                                      stmt2 ...))))))
       (let ((if #t))
         (when if (set! if 'now))
         if))                               ==>  now

     (let ((x 'outer))
       (let-syntax ((m (syntax-rules () ((m) x))))
         (let ((x 'inner))
           (m))))                           ==>  outer

 - syntax: letrec-syntax <bindings> <body>
     *Syntax:* Same as for `let-syntax'.

     *Semantics:*  The <body> is expanded in the syntactic environment
     obtained by extending the syntactic environment of the
     `letrec-syntax' expression with macros whose keywords are the
     <keyword>s, bound to the specified transformers.  Each binding of
     a <keyword> has the <bindings> as well as the <body> within its
     region, so the transformers can transcribe expressions into uses
     of the macros introduced by the `letrec-syntax' expression.

     (letrec-syntax
       ((or (syntax-rules ()
              ((or) #f)
              ((or e) e)
              ((or e1 e2 ...)
               (let ((temp e1))
                 (if temp
                     temp
                     (or e2 ...)))))))
       (let ((x #f)
             (y 7)
             (temp 8)
             (let odd?)
             (if even?))
         (or x
             (let temp)
             (if y)
             y)))                           ==>  7

 - : define-syntax <keyword> <transformer spec>
     *Syntax:* The <keyword> is an identifier, and the <transformer
     spec> should be an instance of `syntax-rules'.

     *Semantics:* The top-level syntactic environment is extended by
     binding the <keyword> to the specified transformer.

     (define-syntax let*
       (syntax-rules ()
         ((let* () body1 body2 ...)
          (let () body1 body2 ...))
         ((let* ((name1 val1) (name2 val2) ...)
            body1 body2 ...)
          (let ((name1 val1))
            (let* ((name2 val2) ...)
              body1 body2 ...)))))

Pattern language
================

 - : syntax-rules <literals> <syntax rule> ...,
     *Syntax:* <Literals> is a list of identifiers, and each <syntax
     rule> should be of the form

     (<pattern> <template>)

     where the <pattern> and <template> are as in the grammar above.

     *Semantics:* An instance of `syntax-rules' produces a new macro
     transformer by specifying a sequence of hygienic rewrite rules.  A
     use of a macro whose keyword is associated with a transformer
     specified by `syntax-rules' is matched against the patterns
     contained in the <syntax rule>s, beginning with the leftmost
     <syntax rule>.  When a match is found, the macro use is
     transcribed hygienically according to the template.

     Each pattern begins with the keyword for the macro.  This keyword
     is not involved in the matching and is not considered a pattern
     variable or literal identifier.

          *Rationale:* The scope of the keyword is determined by the
          expression or syntax definition that binds it to the
          associated macro transformer.  If the keyword were a pattern
          variable or literal identifier, then the template that
          follows the pattern would be within its scope regardless of
          whether the keyword were bound by `let-syntax' or by
          `letrec-syntax'.

     An identifier that appears in the pattern of a <syntax rule> is a
     pattern variable, unless it is the keyword that begins the pattern,
     is listed in <literals>, or is the identifier "`...'".  Pattern
     variables match arbitrary input elements and are used to refer to
     elements of the input in the template.  It is an error for the
     same pattern variable to appear more than once in a <pattern>.

     Identifiers that appear in <literals> are interpreted as literal
     identifiers to be matched against corresponding subforms of the
     input.  A subform in the input matches a literal identifier if and
     only if it is an identifier and either both its occurrence in the
     macro expression and its occurrence in the macro definition have
     the same lexical binding, or the two identifiers are equal and
     both have no lexical binding.

     A subpattern followed by `...' can match zero or more elements of
     the input.  It is an error for `...' to appear in <literals>.
     Within a pattern the identifier `...' must follow the last element
     of a nonempty sequence of subpatterns.

     More formally, an input form F matches a pattern P if and only if:

        * P is a pattern variable; or

        * P is a literal identifier and F is an identifier with the same
          binding; or

        * P is a pattern list `(P_1 ... P_n)' and F is a list of n
          forms that match P_1 through P_n, respectively; or

        * P is an improper pattern list `(P_1 P_2 ... P_n . P_n+1)' and
          F is a list or improper list of n or more forms that match
          P_1 through P_n, respectively, and whose nth "cdr" matches
          P_n+1; or

        * P is       of the form `(P_1 ... P_n P_n+1 <ellipsis>)' where
          <ellipsis> is the identifier `...' and F is a proper list of
          at least n elements, the first n of which match P_1 through
          P_n, respectively, and each remaining element of F matches
          P_n+1; or

        * P is a pattern datum and F is equal to P in the sense of the
          `equal?' procedure.

     It is an error to use a macro keyword, within the scope of its
     binding, in an expression that does not match any of the patterns.

     When a macro use is transcribed according to the template of the
     matching <syntax rule>, pattern variables that occur in the
     template are replaced by the subforms they match in the input.
     Pattern variables that occur in subpatterns followed by one or more
     instances of the identifier `...' are allowed only in subtemplates
     that are followed by as many instances of `...'.  They are
     replaced in the output by all of the subforms they match in the
     input, distributed as indicated.  It is an error if the output
     cannot be built up as specified.

     Identifiers that appear in the template but are not pattern
     variables or the identifier `...' are inserted into the output as
     literal identifiers.  If a literal identifier is inserted as a
     free identifier then it refers to the binding of that identifier
     within whose scope the instance of `syntax-rules' appears.  If a
     literal identifier is inserted as a bound identifier then it is in
     effect renamed to prevent inadvertent captures of free identifiers.

     (define-syntax let
       (syntax-rules ()
         ((let ((name val) ...) body1 body2 ...)
          ((lambda (name ...) body1 body2 ...)
           val ...))
         ((let tag ((name val) ...) body1 body2 ...)
          ((letrec ((tag (lambda (name ...)
                           body1 body2 ...)))
             tag)
           val ...))))

     (define-syntax cond
       (syntax-rules (else =>)
         ((cond (else result1 result2 ...))
          (begin result1 result2 ...))
         ((cond (test => result))
          (let ((temp test))
            (if temp (result temp))))
         ((cond (test => result) clause1 clause2 ...)
          (let ((temp test))
            (if temp
                (result temp)
                (cond clause1 clause2 ...))))
         ((cond (test)) test)
         ((cond (test) clause1 clause2 ...)
          (or test (cond clause1 clause2 ...)))
         ((cond (test result1 result2 ...))
          (if test (begin result1 result2 ...)))
         ((cond (test result1 result2 ...)
                clause1 clause2 ...)
          (if test
              (begin result1 result2 ...)
              (cond clause1 clause2 ...)))))

     (let ((=> #f))
       (cond (#t => 'ok)))                  ==> ok

     The last example is not an error because the local variable `=>'
     is renamed in effect, so that its use is distinct from uses of the
     top level identifier `=>' that the transformer for `cond' looks
     for.  Thus, rather than expanding into

     (let ((=> #f))
       (let ((temp #t))
         (if temp ('ok temp))))

     which would result in an invalid procedure call, it expands instead
     into

     (let ((=> #f))
       (if #t (begin => 'ok)))