This is r5rs.info, produced by makeinfo version 4.2 from r5rs.texi.

INFO-DIR-SECTION The Algorithmic Language Scheme
START-INFO-DIR-ENTRY
* R5RS: (r5rs).                 The Revised(5) Report on Scheme.
END-INFO-DIR-ENTRY

20 February 1998


File: r5rs.info,  Node: Strings,  Next: Vectors,  Prev: Characters,  Up: Other data types

Strings
-------

Strings are sequences of characters.  Strings are written as sequences
of characters enclosed within doublequotes (`"').  A doublequote can be
written inside a string only by escaping it with a backslash (\), as in


     "The word \"recursion\" has many meanings."

A backslash can be written inside a string only by escaping it with
another backslash.  Scheme does not specify the effect of a backslash
within a string that is not followed by a doublequote or backslash.

A string constant may continue from one line to the next, but the exact
contents of such a string are unspecified.

The _length_ of a string is the number of characters that it contains.
This number is an exact, non-negative integer that is fixed when the
string is created.  The "valid indexes" of a string are the exact
non-negative integers less than the length of the string.  The first
character of a string has index 0, the second has index 1, and so on.

In phrases such as "the characters of STRING beginning with index START
and ending with index END," it is understood that the index START is
inclusive and the index END is exclusive.  Thus if START and END are
the same index, a null substring is referred to, and if START is zero
and END is the length of STRING, then the entire string is referred to.

Some of the procedures that operate on strings ignore the difference
between upper and lower case.  The versions that ignore case have
"`-ci'" (for "case insensitive") embedded in their names.

 - procedure: string? obj
     Returns #t if OBJ is a string, otherwise returns #f.

 - procedure: make-string K
 - procedure: make-string K char
     `Make-string' returns a newly allocated string of length K.  If
     CHAR is given, then all elements of the string are initialized to
     CHAR, otherwise the contents of the STRING are unspecified.


 - library procedure: string char ...,
     Returns a newly allocated string composed of the arguments.


 - procedure: string-length string
     Returns the number of characters in the given STRING.

 - procedure: string-ref string K
     K must be a valid index of STRING.  `String-ref' returns character
     K of STRING using zero-origin indexing.

 - procedure: string-set! string k char
     K must be a valid index of STRING .  `String-set!' stores CHAR in
     element K of STRING and returns an unspecified value.

     (define (f) (make-string 3 #\*))
     (define (g) "***")
     (string-set! (f) 0 #\?)                ==>  _unspecified_
     (string-set! (g) 0 #\?)                ==>  _error_
     (string-set! (symbol->string 'immutable)
                  0
                  #\?)                      ==>  _error_


 - library procedure: string=? string1 string2
 - library procedure: string-ci=? string1 string2
     Returns #t if the two strings are the same length and contain the
     same characters in the same positions, otherwise returns #f.
     `String-ci=?' treats upper and lower case letters as though they
     were the same character, but `string=?' treats upper and lower
     case as distinct characters.


 - library procedure: string<? string1 string2
 - library procedure: string>? string1 string2
 - library procedure: string<=? string1 string2
 - library procedure: string>=? string1 string2
 - library procedure: string-ci<? string1 string2
 - library procedure: string-ci>? string1 string2
 - library procedure: string-ci<=? string1 string2
 - library procedure: string-ci>=? string1 string2
     These procedures are the lexicographic extensions to strings of the
     corresponding orderings on characters.  For example, `string<?' is
     the lexicographic ordering on strings induced by the ordering
     `char<?' on characters.  If two strings differ in length but are
     the same up to the length of the shorter string, the shorter string
     is considered to be lexicographically less than the longer string.

     Implementations may generalize these and the `string=?' and
     `string-ci=?' procedures to take more than two arguments, as with
     the corresponding numerical predicates.


 - library procedure: substring string start end
     STRING must be a string, and START and END must be exact integers
     satisfying

                0 <= START <= END <= (string-length STRING).
 `Substring' returns a
     newly allocated string formed from the characters of STRING
     beginning with index START (inclusive) and ending with index END
     (exclusive).

 - library procedure: string-append STRING ...,
     Returns a newly allocated string whose characters form the
     concatenation of the given strings.


 - library procedure: string->list string
 - library procedure: list->string list
     `String->list' returns a newly allocated list of the characters
     that make up the given string.  `List->string' returns a newly
     allocated string formed from the characters in the list LIST,
     which must be a list of characters. `String->list' and
     `list->string' are inverses so far as `equal?' is concerned.


 - library procedure: string-copy string
     Returns a newly allocated copy of the given STRING.


 - library procedure: string-fill! string char
     Stores CHAR in every element of the given STRING and returns an
     unspecified value.



File: r5rs.info,  Node: Vectors,  Prev: Strings,  Up: Other data types

Vectors
-------

Vectors are heterogenous structures whose elements are indexed by
integers.  A vector typically occupies less space than a list of the
same length, and the average time required to access a randomly chosen
element is typically less for the vector than for the list.

The _length_ of a vector is the number of elements that it contains.
This number is a non-negative integer that is fixed when the vector is
created.  The _valid indexes_ of a vector are the exact non-negative
integers less than the length of the vector.  The first element in a
vector is indexed by zero, and the last element is indexed by one less
than the length of the vector.

Vectors are written using the notation #(OBJ ...,).  For example, a
vector of length 3 containing the number zero in element 0, the list
`(2 2 2 2)' in element 1, and the string `"Anna"' in element 2 can be
written as following:


     #(0 (2 2 2 2) "Anna")

Note that this is the external representation of a vector, not an
expression evaluating to a vector.  Like list constants, vector
constants must be quoted:


     '#(0 (2 2 2 2) "Anna")
               ==>  #(0 (2 2 2 2) "Anna")

 - procedure: vector? obj
     Returns #t if OBJ is a vector, otherwise returns #f.

 - procedure: make-vector k
 - procedure: make-vector k fill
     Returns a newly allocated vector of K elements.  If a second
     argument is given, then each element is initialized to FILL.
     Otherwise the initial contents of each element is unspecified.


 - library procedure: vector obj ...,
     Returns a newly allocated vector whose elements contain the given
     arguments.  Analogous to `list'.

     (vector 'a 'b 'c)                      ==>  #(a b c)


 - procedure: vector-length vector
     Returns the number of elements in VECTOR as an exact integer.

 - procedure: vector-ref vector k
     K must be a valid index of VECTOR.  `Vector-ref' returns the
     contents of element K of VECTOR.

     (vector-ref '#(1 1 2 3 5 8 13 21)
                 5)
               ==>  8
     (vector-ref '#(1 1 2 3 5 8 13 21)
                 (let ((i (round (* 2 (acos -1)))))
                   (if (inexact? i)
                       (inexact->exact i)
                       i)))
               ==> 13


 - procedure: vector-set! vector k obj
     K must be a valid index of VECTOR.  `Vector-set!' stores OBJ in
     element K of VECTOR.  The value returned by `vector-set!' is
     unspecified.

     (let ((vec (vector 0 '(2 2 2 2) "Anna")))
       (vector-set! vec 1 '("Sue" "Sue"))
       vec)
               ==>  #(0 ("Sue" "Sue") "Anna")
     
     (vector-set! '#(0 1 2) 1 "doe")
               ==>  _error_  ; constant vector


 - library procedure: vector->list vector
 - library procedure: list->vector list
     `Vector->list' returns a newly allocated list of the objects
     contained in the elements of VECTOR.  `List->vector' returns a
     newly created vector initialized to the elements of the list LIST.

     (vector->list '#(dah dah didah))
               ==>  (dah dah didah)
     (list->vector '(dididit dah))
               ==>  #(dididit dah)


 - library procedure: vector-fill! vector fill
     Stores FILL in every element of VECTOR.  The value returned by
     `vector-fill!' is unspecified.



File: r5rs.info,  Node: Control features,  Next: Eval,  Prev: Other data types,  Up: Standard procedures

Control features
================

This chapter describes various primitive procedures which control the
flow of program execution in special ways.  The `procedure?' predicate
is also described here.

 - procedure: procedure? obj
     Returns #t if OBJ is a procedure, otherwise returns #f.

     (procedure? car)                       ==>  #t
     (procedure? 'car)                      ==>  #f
     (procedure? (lambda (x) (* x x)))
                                            ==>  #t
     (procedure? '(lambda (x) (* x x)))
                                            ==>  #f
     (call-with-current-continuation procedure?)
                                            ==>  #t


 - procedure: apply proc arg1 ... args
     PROC must be a procedure and ARGS must be a list.  Calls PROC with
     the elements of the list `(append (list ARG1 ...,) ARGS)' as the
     actual arguments.

     (apply + (list 3 4))                   ==>  7
     
     (define compose
       (lambda (f g)
         (lambda args
           (f (apply g args)))))
     
     ((compose sqrt *) 12 75)               ==>  30


 - library procedure: map proc list1 list2 ...,
     The LISTs must be lists, and PROC must be a procedure taking as
     many arguments as there are lists and returning a single value.
     If more than one LIST is given, then they must all be the same
     length.  `Map' applies PROC element-wise to the elements of the
     LISTs and returns a list of the results, in order.  The dynamic
     order in which PROC is applied to the elements of the LISTs is
     unspecified.

     (map cadr '((a b) (d e) (g h)))
               ==>  (b e h)
     
     (map (lambda (n) (expt n n))
          '(1 2 3 4 5))
               ==>  (1 4 27 256 3125)
     
     (map + '(1 2 3) '(4 5 6))              ==>  (5 7 9)
     
     (let ((count 0))
       (map (lambda (ignored)
              (set! count (+ count 1))
              count)
            '(a b)))                        ==>  (1 2) OR (2 1)


 - library procedure: for-each proc list1 list2 ...,
     The arguments to `for-each' are like the arguments to `map', but
     `for-each' calls PROC for its side effects rather than for its
     values.  Unlike `map', `for-each' is guaranteed to call PROC on
     the elements of the LISTs in order from the first element(s) to the
     last, and the value returned by `for-each' is unspecified.

     (let ((v (make-vector 5)))
       (for-each (lambda (i)
                   (vector-set! v i (* i i)))
                 '(0 1 2 3 4))
       v)                                   ==>  #(0 1 4 9 16)


 - library procedure: force promise
     Forces the value of PROMISE (see `delay', section *note Delayed
     evaluation::).  If no value has been computed for the promise,
     then a value is computed and returned.  The value of the promise
     is cached (or "memoized") so that if it is forced a second time,
     the previously computed value is returned.

     (force (delay (+ 1 2)))                ==>  3
     (let ((p (delay (+ 1 2))))
       (list (force p) (force p)))
                                            ==>  (3 3)
     
     (define a-stream
       (letrec ((next
                 (lambda (n)
                   (cons n (delay (next (+ n 1)))))))
         (next 0)))
     (define head car)
     (define tail
       (lambda (stream) (force (cdr stream))))
     
     (head (tail (tail a-stream)))
                                            ==>  2

     `Force' and `delay' are mainly intended for programs written in
     functional style.  The following examples should not be considered
     to illustrate good programming style, but they illustrate the
     property that only one value is computed for a promise, no matter
     how many times it is forced.

     (define count 0)
     (define p
       (delay (begin (set! count (+ count 1))
                     (if (> count x)
                         count
                         (force p)))))
     (define x 5)
     p                                      ==>  a promise
     (force p)                              ==>  6
     p                                      ==>  a promise, still
     (begin (set! x 10)
            (force p))                      ==>  6

     Here is a possible implementation of `delay' and `force'.
     Promises are implemented here as procedures of no arguments, and
     `force' simply calls its argument:

     (define force
       (lambda (object)
         (object)))

     We define the expression

     (delay <expression>)

     to have the same meaning as the procedure call

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

     as follows

     (define-syntax delay
       (syntax-rules ()
         ((delay expression)
          (make-promise (lambda () expression))))),

     where `make-promise' is defined as follows:

     (define make-promise
       (lambda (proc)
         (let ((result-ready? #f)
               (result #f))
           (lambda ()
             (if result-ready?
                 result
                 (let ((x (proc)))
                   (if result-ready?
                       result
                       (begin (set! result-ready? #t)
                              (set! result x)
                              result))))))))

          _Rationale:_ A promise may refer to its own value, as in the
          last example above.  Forcing such a promise may cause the
          promise to be forced a second time before the value of the
          first force has been computed.  This complicates the
          definition of `make-promise'.

     Various extensions to this semantics of `delay' and `force' are
     supported in some implementations:

        * Calling `force' on an object that is not a promise may simply
          return the object.

        * It may be the case that there is no means by which a promise
          can be operationally distinguished from its forced value.
          That is, expressions like the following may evaluate to
          either #t or to #f, depending on the implementation:

          (eqv? (delay 1) 1)                ==>  _unspecified_
          (pair? (delay (cons 1 2)))        ==>  _unspecified_

        * Some implementations may implement "implicit forcing," where
          the value of a promise is forced by primitive procedures like
          `cdr' and `+':

          (+ (delay (* 3 7)) 13)            ==>  34



 - procedure: call-with-current-continuation proc
     PROC must be a procedure of one argument. The procedure
     `call-with-current-continuation' packages up the current
     continuation (see the rationale below) as an "escape procedure"
     and passes it as an argument to PROC.  The escape procedure is a
     Scheme procedure that, if it is later called, will abandon
     whatever continuation is in effect at that later time and will
     instead use the continuation that was in effect when the escape
     procedure was created.  Calling the escape procedure may cause the
     invocation of BEFORE and AFTER thunks installed using
     `dynamic-wind'.

     The escape procedure accepts the same number of arguments as the
     continuation to the original call to
     call-with-current-continuation.  Except for continuations created
     by the `call-with-values' procedure, all continuations take
     exactly one value.  The effect of passing no value or more than
     one value to continuations that were not created by
     call-with-values is unspecified.

     The escape procedure that is passed to PROC has unlimited extent
     just like any other procedure in Scheme.  It may be stored in
     variables or data structures and may be called as many times as
     desired.

     The following examples show only the most common ways in which
     `call-with-current-continuation' is used.  If all real uses were as
     simple as these examples, there would be no need for a procedure
     with the power of `call-with-current-continuation'.

     (call-with-current-continuation
       (lambda (exit)
         (for-each (lambda (x)
                     (if (negative? x)
                         (exit x)))
                   '(54 0 37 -3 245 19))
         #t))                               ==>  -3
     
     (define list-length
       (lambda (obj)
         (call-with-current-continuation
           (lambda (return)
             (letrec ((r
                       (lambda (obj)
                         (cond ((null? obj) 0)
                               ((pair? obj)
                                (+ (r (cdr obj)) 1))
                               (else (return #f))))))
               (r obj))))))
     
     (list-length '(1 2 3 4))               ==>  4
     
     (list-length '(a b . c))               ==>  #f

          _Rationale:_

          A common use of `call-with-current-continuation' is for
          structured, non-local exits from loops or procedure bodies,
          but in fact `call-with-current-continuation' is extremely
          useful for implementing a wide variety of advanced control
          structures.

          Whenever a Scheme expression is evaluated there is a
          "continuation" wanting the result of the expression.  The
          continuation represents an entire (default) future for the
          computation.  If the expression is evaluated at top level,
          for example, then the continuation might take the result,
          print it on the screen, prompt for the next input, evaluate
          it, and so on forever.  Most of the time the continuation
          includes actions specified by user code, as in a continuation
          that will take the result, multiply it by the value stored in
          a local variable, add seven, and give the answer to the top
          level continuation to be printed.  Normally these ubiquitous
          continuations are hidden behind the scenes and programmers do
          not think much about them.  On rare occasions, however, a
          programmer may need to deal with continuations explicitly.
          `Call-with-current-continuation' allows Scheme programmers to
          do that by creating a procedure that acts just like the
          current continuation.

          Most programming languages incorporate one or more
          special-purpose escape constructs with names like exit,
          `return', or even goto.  In 1965, however, Peter Landin
          [Landin65] invented a general purpose escape operator called
          the J-operator.  John Reynolds [Reynolds72] described a
          simpler but equally powerful construct in 1972.  The `catch'
          special form described by Sussman and Steele in the 1975
          report on Scheme is exactly the same as Reynolds's construct,
          though its name came from a less general construct in
          MacLisp.  Several Scheme implementors noticed that the full
          power of the `catch' construct could be provided by a
          procedure instead of by a special syntactic construct, and
          the name `call-with-current-continuation' was coined in 1982.
          This name is descriptive, but opinions differ on the merits
          of such a long name, and some people use the name `call/cc'
          instead.


 - procedure: values obj ...
     Delivers all of its arguments to its continuation.  Except for
     continuations created by the `call-with-values' procedure, all
     continuations take exactly one value.  Values might be defined as
     follows:

     (define (values . things)
       (call-with-current-continuation
         (lambda (cont) (apply cont things))))


 - procedure: call-with-values producer consumer
     Calls its PRODUCER argument with no values and a continuation
     that, when passed some values, calls the CONSUMER procedure with
     those values as arguments.  The continuation for the call to
     CONSUMER is the continuation of the call to call-with-values.

     (call-with-values (lambda () (values 4 5))
                       (lambda (a b) b))
                                                        ==>  5
     
     (call-with-values * -)                             ==>  -1


 - procedure: dynamic-wind before thunk after
     Calls THUNK without arguments, returning the result(s) of this
     call.  BEFORE and AFTER are called, also without arguments, as
     required by the following rules (note that in the absence of calls
     to continuations captured using `call-with-current-continuation'
     the three arguments are called once each, in order).  BEFORE is
     called whenever execution enters the dynamic extent of the call to
     THUNK and AFTER is called whenever it exits that dynamic extent.
     The dynamic extent of a procedure call is the period between when
     the call is initiated and when it returns.  In Scheme, because of
     `call-with-current-continuation', the dynamic extent of a call may
     not be a single, connected time period.  It is defined as follows:

        * The dynamic extent is entered when execution of the body of
          the called procedure begins.

        * The dynamic extent is also entered when execution is not
          within the dynamic extent and a continuation is invoked that
          was captured (using `call-with-current-continuation') during
          the dynamic extent.

        * It is exited when the called procedure returns.

        * It is also exited when execution is within the dynamic extent
          and a continuation is invoked that was captured while not
          within the dynamic extent.


     If a second call to `dynamic-wind' occurs within the dynamic
     extent of the call to THUNK and then a continuation is invoked in
     such a way that the AFTERs from these two invocations of
     `dynamic-wind' are both to be called, then the AFTER associated
     with the second (inner) call to `dynamic-wind' is called first.

     If a second call to `dynamic-wind' occurs within the dynamic
     extent of the call to THUNK and then a continuation is invoked in
     such a way that the BEFOREs from these two invocations of
     `dynamic-wind' are both to be called, then the BEFORE associated
     with the first (outer) call to `dynamic-wind' is called first.

     If invoking a continuation requires calling the BEFORE from one
     call to `dynamic-wind' and the AFTER from another, then the AFTER
     is called first.

     The effect of using a captured continuation to enter or exit the
     dynamic extent of a call to BEFORE or AFTER is undefined.

     (let ((path '())
           (c #f))
       (let ((add (lambda (s)
                    (set! path (cons s path)))))
         (dynamic-wind
           (lambda () (add 'connect))
           (lambda ()
             (add (call-with-current-continuation
                    (lambda (c0)
                      (set! c c0)
                      'talk1))))
           (lambda () (add 'disconnect)))
         (if (< (length path) 4)
             (c 'talk2)
             (reverse path))))
     
               ==> (connect talk1 disconnect
                    connect talk2 disconnect)



File: r5rs.info,  Node: Eval,  Next: Input and output,  Prev: Control features,  Up: Standard procedures

Eval
====

 - procedure: eval expression environment-specifier
     Evaluates EXPRESSION in the specified environment and returns its
     value.  EXPRESSION must be a valid Scheme expression represented
     as data, and ENVIRONMENT-SPECIFIER must be a value returned by one
     of the three procedures described below.  Implementations may
     extend `eval' to allow non-expression programs (definitions) as
     the first argument and to allow other values as environments, with
     the restriction that `eval' is not allowed to create new bindings
     in the environments associated with `null-environment' or
     `scheme-report-environment'.

     (eval '(* 7 3) (scheme-report-environment 5))
                                                        ==>  21
     
     (let ((f (eval '(lambda (f x) (f x x))
                    (null-environment 5))))
       (f + 10))
                                                        ==>  20


 - procedure: scheme-report-environment version
 - procedure: null-environment version
     VERSION must be the exact integer `5', corresponding to this
     revision of the Scheme report (the Revised^5 Report on Scheme).
     `Scheme-report-environment' returns a specifier for an environment
     that is empty except for all bindings defined in this report that
     are either required or both optional and supported by the
     implementation. `Null-environment' returns a specifier for an
     environment that is empty except for the (syntactic) bindings for
     all syntactic keywords defined in this report that are either
     required or both optional and supported by the implementation.

     Other values of VERSION can be used to specify environments
     matching past revisions of this report, but their support is not
     required.  An implementation will signal an error if VERSION is
     neither `5' nor another value supported by the implementation.

     The effect of assigning (through the use of `eval') a variable
     bound in a `scheme-report-environment' (for example `car') is
     unspecified.  Thus the environments specified by
     `scheme-report-environment' may be immutable.


 - optional procedure: interaction-environment
     This procedure returns a specifier for the environment that
     contains implementation-defined bindings, typically a superset of
     those listed in the report.  The intent is that this procedure
     will return the environment in which the implementation would
     evaluate expressions dynamically typed by the user.



File: r5rs.info,  Node: Input and output,  Prev: Eval,  Up: Standard procedures

Input and output
================

* Menu:

* Ports::
* Input::
* Output::
* System interface::


File: r5rs.info,  Node: Ports,  Next: Input,  Prev: Input and output,  Up: Input and output

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.

 - library procedure: call-with-input-file string proc
 - library procedure: call-with-output-file string proc
     STRING should be a string naming a file, and PROC should be a
     procedure that accepts one argument.  For `call-with-input-file',
     the file should 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 PROC returns, then the port is closed
     automatically and the value(s) yielded by the PROC is(are)
     returned.  If PROC 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'.



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


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


 - optional procedure: with-input-from-file string thunk
 - optional procedure: with-output-to-file string thunk
     STRING should be a string naming a file, and PROC should be a
     procedure of no arguments.  For `with-input-from-file', the file
     should 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 is used by (read), (write OBJ), and so
     forth), 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(s) the
     value(s) yielded by THUNK.  If an escape procedure is used to
     escape from the continuation of these procedures, their behavior
     is implementation dependent.


 - 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.


 - 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.


 - procedure: close-input-port port
 - 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.



File: r5rs.info,  Node: Input,  Next: Output,  Prev: Ports,  Up: Input and output

Input
-----

 





 - library procedure: read
 - library 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 *note External representation:: and *note
     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.

 - procedure: read-char
 - 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'.


 - procedure: peek-char
 - 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.


 - 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.



File: r5rs.info,  Node: Output,  Next: System interface,  Prev: Input,  Up: Input and output

Output
------






 - library procedure: write obj
 - library 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.  Character objects are
     written using the `#\' notation.  `Write' returns an unspecified
     value.  The PORT argument may be omitted, in which case it
     defaults to the value returned by `current-output-port'.


 - library procedure: display obj
 - library 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.


 - library procedure: newline
 - library 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'.


 - procedure: write-char char
 - 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'.



File: r5rs.info,  Node: System interface,  Prev: Output,  Up: Input and output

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.

 - optional 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.


 - optional procedure: transcript-on filename
 - optional 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.



File: r5rs.info,  Node: Formal syntax and semantics,  Next: Notes,  Prev: Standard procedures,  Up: Top

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

* Menu:

* Formal syntax::
* Formal semantics::
* Derived expression type::

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


File: r5rs.info,  Node: Formal syntax,  Next: Formal semantics,  Prev: Formal syntax and semantics,  Up: Formal syntax and semantics

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

* Menu:

* Lexical structure::
* External representation::
* Expression::
* Quasiquotations::
* Transformers::
* Programs and definitions::

This section provides a formal syntax for Scheme written in an extended
BNF.

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>.


File: r5rs.info,  Node: Lexical structure,  Next: External representation,  Prev: Formal syntax,  Up: Formal syntax

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.

The following five characters are reserved for future extensions to the
language: [ ] { } |

<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


File: r5rs.info,  Node: External representation,  Next: Expression,  Prev: Lexical structure,  Up: Formal syntax

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

<Datum> is what the `read' procedure (section *note 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>*)


File: r5rs.info,  Node: Expression,  Next: Quasiquotations,  Prev: External representation,  Up: Formal syntax

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

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

<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> <do result>)
         <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>
<do result> --> <sequence> | <empty>

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

<macro block> -->
     (let-syntax (<syntax spec>*) <body>)
     | (letrec-syntax (<syntax spec>*) <body>)
<syntax spec> --> (<keyword> <transformer spec>)


File: r5rs.info,  Node: Quasiquotations,  Next: Transformers,  Prev: Expression,  Up: Formal syntax

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

In <quasiquotation>s, a <list qq 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.


File: r5rs.info,  Node: Transformers,  Next: Programs and definitions,  Prev: Quasiquotations,  Up: Formal syntax

Transformers
------------

<transformer spec> -->
    (syntax-rules (<identifier>*) <syntax rule>*)
<syntax rule> --> (<pattern> <template>)
<pattern> --> <pattern identifier>
     | (<pattern>*)
     | (<pattern>+ . <pattern>)
     | (<pattern>* <pattern> <ellipsis>)
     | #(<pattern>*)
     | #(<pattern>* <pattern> <ellipsis>)
     | <pattern datum>
<pattern datum> --> <string>
     | <character>
     | <boolean>
     | <number>
<template> --> <pattern identifier>
     | (<template element>*)
     | (<template element>+ . <template>)
     | #(<template element>*)
     | <template datum>
<template element> --> <template>
     | <template> <ellipsis>
<template datum> --> <pattern datum>
<pattern identifier> --> <any identifier except `...'>
<ellipsis> --> <the identifier `...'>


File: r5rs.info,  Node: Programs and definitions,  Prev: Transformers,  Up: Formal syntax

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

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


File: r5rs.info,  Node: Formal semantics,  Next: Derived expression type,  Prev: Formal syntax,  Up: Formal syntax and semantics

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.

