Common Lisp the Language, 2nd Edition
Next: Streams
Up: The Evaluator
Previous: Run-Time Evaluation
of
Normally one interacts with Lisp through a ``top-level
read
-eval
-print
loop,’’ so called
because it is the highest level of control and consists of an endless
loop that reads an expression, evaluates it, and prints the results. One
has an effect on the state of the Lisp system only by invoking actions
that have side effects.
The precise nature of the top-level loop for Common Lisp is purposely not rigorously specified here so that implementors can experiment to improve the user interface. For example, an implementor may choose to require line-at-a-time input, or may provide a fancy editor or complex graphics-display interface. An implementor may choose to provide explicit prompts for input, or may choose (as MacLisp does) not to clutter up the transcript with prompts.
The top-level loop is required to trap all throws and recover gracefully. It is also required to print all values resulting from evaluation of a form, perhaps on separate lines. If a form returns zero values, as little as possible should be printed.
The following variables are maintained by the top-level loop as a limited safety net, in case the user forgets to save an interesting input expression or output value. (Note that the names of some of these variables violate the convention that names of global variables begin and end with an asterisk.) These are intended primarily for user interaction, which is why they have short names. Use of these variables should be avoided in programs.
[Variable]
+
++
+++
While a form is being evaluated by the top-level loop, the variable
+
is bound to the previous form read by the loop. The
variable ++
holds the previous value of +
(that is, the form evaluated two interactions ago), and +++
holds the previous value of ++
.
[Variable]
-
While a form is being evaluated by the top-level loop, the variable
-
is bound to the form itself; that is, it is the value
about to be given to +
once this interaction is done.
Notice of correction. In the first edition, the name of the
variable -
was inadvertently omitted.
[Variable]
*
**
***
While a form is being evaluated by the top-level loop, the variable
*
is bound to the result printed at the end of the last
time through the loop; that is, it is the value produced by evaluating
the form in +
. If several values were produced,
*
contains the first value only; *
contains
nil
if zero values were produced. The variable
**
holds the previous value of *
(that is, the
result printed two interactions ago), and ***
holds the
previous value of **
.
If the evaluation of +
is aborted for some reason, then
the values associated with *
, **
, and
***
are not updated; they are updated only if the printing
of values is at least begun (though not necessarily completed).
[Variable]
/
//
///
While a form is being evaluated by the top-level loop, the variable
/
is bound to a list of the results printed at the end of
the last time through the loop; that is, it is a list of all values
produced by evaluating the form in +
. The value of
*
should always be the same as the car of the
value of /
. The variable //
holds the previous
value of /
(that is, the results printed two interactions
ago), and ///
holds the previous value of //
.
Therefore the value of **
should always be the same as the
car of //
, and similarly for ***
and
///
.
If the evaluation of +
is aborted for some reason, then
the values associated with /
, //
, and
///
are not updated; they are updated only if the printing
of values is at least begun (though not necessarily completed).
As an example of the processing of these variables, consider the
following possible transcript, where >
is a prompt by
the top-level loop for user input:
>(cons - -) ;Interaction 1
((CONS - -) CONS - -) ;Cute, huh?
>(values) ;Interaction 2
;Nothing to print
>(cons 'a 'b) ;Interaction 3
(A . B) ;There is a single value
>(hairy-loop)^G ;Interaction 4
### QUIT to top level. ;(User aborts the computation.)
>(floor 13 4) ;Interaction 5
3 ;There are two values
1
At this point we have:
+++ => (cons 'a 'b) *** => NIL /// => ()
++ => (hairy-loop) ** => (A . B) // => ((A . B))
+ => (floor 13 4) * => 3 / => (3 1)
Next: Streams
Up: The Evaluator
Previous: Run-Time Evaluation
of
AI.Repository@cs.cmu.edu