Common Lisp the Language, 2nd Edition
Next: Environment Inquiries
Up: Miscellaneous Features
Previous: Documentation
The utilities described in this section are sufficiently complex and sufficiently dependent on the host environment that their complete definition is beyond the scope of this book. However, they are also sufficiently useful to warrant mention here. It is expected that every implementation will provide some version of these utilities, however clever or however simple.
[Macro]
trace {
function-name
}*
untrace {
function-name
}*
Invoking trace
with one or more function-names (symbols)
causes the functions named to be traced. Henceforth, whenever such a
function is invoked, information about the call, the arguments passed,
and the eventually returned values, if any, will be printed to the
stream that is the value of *trace-output*
.
For example:
(trace fft gcd string-upcase)
If a function call is open-coded (possibly as a result of an
inline
declaration), then such a call may not produce trace
output.
Invoking untrace
with one or more function names will
cause those functions not to be traced any more.
Tracing an already traced function, or untracing a function not currently being traced, should produce no harmful effects but may produce a warning message.
Calling trace
with no argument forms will return a list
of functions currently being traced.
Calling untrace
with no argument forms will cause all
currently traced functions to be no longer traced.
X3J13 voted in March 1989 (FUNCTION-NAME) to extend trace
and untrace
to accept any function-name (a symbol or a list
whose car is setf
- see section 7.1). Thus one may write
(trace (setf cadr))
to trace the setf
expansion function for cadr
.
X3J13 voted in January 1989 (RETURN-VALUES-UNSPECIFIED) to specify
that the values returned by trace
and untrace
when given argument forms are implementation-dependent.
trace
and untrace
may also accept
additional implementation-dependent argument formats. The format of the
trace output is implementation-dependent.
[Macro]
step
form
This evaluates form and returns what form returns.
However, the user is allowed to interactively ``single-step’’ through
the evaluation of form, at least through those evaluation steps
that are performed interpretively. The nature of the interaction is
implementation-dependent. However, implementations are encouraged to
respond to the typing of the character ?
by providing help,
including a list of commands.
X3J13 voted in January 1989 (STEP-ENVIRONMENT) to clarify that
step
evaluates its argument form in the current
lexical environment (not simply a null environment), and that calls to
step
may be compiled, in which case an implementation may
step through only those parts of the evaluation that are interpreted.
(In other words, the form itself is unlikely to be stepped, but
if executing it happens to invoke interpreted code, then that code may
be stepped.)
[Macro]
time
form
This evaluates form and returns what form returns.
However, as a side effect, various timing data and other information are
printed to the stream that is the value of *trace-output*
.
The nature and format of the printed information is
implementation-dependent. However, implementations are encouraged to
provide such information as elapsed real time, machine run time, storage
management statistics, and so on.
Compatibility note: This facility is inspired by the
Interlisp facility of the same name. Note that the MacLisp/Lisp Machine
Lisp function time
does something else entirely, namely
return a quantity indicating relative elapsed real time.
X3J13 voted in January 1989 (STEP-ENVIRONMENT) to clarify that
time
evaluates its argument form in the current
lexical environment (not simply a null environment), and that calls to
time
may be compiled.
[Function]
describe
object
describe
prints, to the stream in the variable
*standard-output*
, information about the object.
Sometimes it will describe something that it finds inside something
else; such recursive descriptions are indented appropriately. For
instance, describe
of a symbol will exhibit the symbol’s
value, its definition, and each of its properties. describe
of a floating-point number will exhibit its internal representation in a
way that is useful for tracking down round-off errors and the like. The
nature and format of the output is implementation-dependent.
describe
returns no values (that is, it returns what the
expression (values)
returns: zero values).
X3J13 voted in March 1989 (DESCRIBE-UNDERSPECIFIED) to let
describe
take an optional second argument:
[Function]
describe
object
&optional
stream
The output is sent to the specified stream, which defaults
to the value of *standard-output*
; the stream may
also be nil
(meaning *standard-output*
) or
t
(meaning *terminal-io*
).
The behavior of describe
depends on the generic function
describe-object
(see below).
X3J13 voted in January 1989 (DESCRIBE-INTERACTIVE) to specify that
describe
is forbidden to prompt for or require user input
when given exactly one argument; it also voted to permit implementations
to extend describe
to accept keyword arguments that may
cause it to prompt for or to require user input.
[Generic function]
describe-object
object
stream
[Primary method]
describe-object (
object
standard-object
)
stream
X3J13 voted in March 1989 (DESCRIBE-UNDERSPECIFIED) to add the
generic function describe-object
, which writes a
description of an object to a stream. The function
describe-object
is called by the describe
function; it should not be called by the user.
Each implementation must provide a method on the class
standard-object
and methods on enough other classes to
ensure that there is always an applicable method. Implementations are
free to add methods for other classes. Users can write methods for
describe-object
for their own classes if they do not wish
to inherit an implementation-supplied method.
The first argument may be any Lisp object. The second argument is a
stream; it cannot be t
or nil
. The values
returned by describe-object
are unspecified.
Methods on describe-object
may recursively call
describe
. Indentation, depth limits, and circularity
detection are all taken care of automatically, provided that each method
handles exactly one level of structure and calls describe
recursively if there are more structural levels. If this rule is not
obeyed, the results are undefined.
In some implementations the stream argument passed to a
describe-object
method is not the original stream but is an
intermediate stream that implements parts of describe
.
Methods should therefore not depend on the identity of this stream.
Rationale: This proposal was closely modeled on the
CLOS description of print-object
, which was well thought
out and provides a great deal of functionality and implementation
freedom. Implementation techniques for print-object
are
applicable to describe-object
.
The reason for making the return values for
describe-object
unspecified is to avoid forcing users to
write (values)
explicitly in all their methods;
describe
should take care of that.
[Function]
inspect
object
inspect
is an interactive version of
describe
. The nature of the interaction is
implementation-dependent, but the purpose of inspect
is to
make it easy to wander through a data structure, examining and modifying
parts of it. Implementations are encouraged to respond to the typing of
the character ?
by providing help, including a list of
commands.
X3J13 voted in January 1989 (RETURN-VALUES-UNSPECIFIED) to specify
that the values returned by inspect
are
implementation-dependent.
[Function]
room &optional
x
room
prints, to the stream in the variable
*standard-output*
, information about the state of internal
storage and its management. This might include descriptions of the
amount of memory in use and the degree of memory compaction, possibly
broken down by internal data type if that is appropriate. The nature and
format of the printed information is implementation-dependent. The
intent is to provide information that may help a user to tune a program
to a particular implementation.
(room nil)
prints out a minimal amount of information.
(room t)
prints out a maximal amount of information. Simply
(room)
prints out an intermediate amount of information
that is likely to be useful.
X3J13 voted in January 1989 (ROOM-DEFAULT-ARGUMENT) to specify that
the argument x may also be the keyword :default
,
which has the same effect as passing no argument at all.
[Function]
ed &optional
x
If the implementation provides a resident editor, this function should invoke it.
(ed)
or (ed nil)
simply enters the editor,
leaving you in the same state as the last time you were in the
editor.
(ed
pathname
)
edits
the contents of the file specified by pathname. The
pathname may be an actual pathname or a string.
X3J13 voted in June 1989 (PATHNAME-LOGICAL) to require ed
to accept logical pathnames (see section 23.1.5).
(ed
symbol
)
tries to
let you edit the text for the function named symbol. The means
by which the function text is obtained is implementation-dependent; it
might involve searching the file system, or pretty printing resident
interpreted code, for example.
X3J13 voted in March 1989 (FUNCTION-NAME) to extend
compile
to accept as a name any function-name (a
symbol or a list whose car is setf
- see section
7.1). Thus one may write
(ed '(setf cadr))
to edit the setf
expansion
function for cadr
.
[Function]
dribble &optional
pathname
(dribble
pathname
)
may
rebind *standard-input*
and *standard-output*
,
and may take other appropriate action, so as to send a record of the
input/output interaction to a file named by pathname. The
primary purpose of this is to create a readable record of an interactive
session.
(dribble)
terminates the recording of input and output
and closes the dribble file.
X3J13 voted in June 1989 (PATHNAME-LOGICAL) to require
dribble
to accept logical pathnames (see section 23.1.5).
X3J13 voted in March 1988 (DRIBBLE-TECHNIQUE) to clarify that
dribble
is intended primarily for interactive debugging and
that its effect cannot be relied upon for use in portable programs.
Different implementations of Common Lisp have used radically
different techniques for implementing dribble
. All are
reasonable interpretations of the original specification, and all behave
in approximately the same way if dribble
is called only
from the interactive top level. However, they may have quite different
behaviors if dribble
is called from within compound
forms.
Consider two models of the operation of dribble
. In the
``redirecting’’ model, a call to dribble
with a pathname
argument alters certain global variables such as
*standard-output*
, perhaps by constructing a broadcast
stream directed to both the original value of
*standard-output*
and to the dribble file; other streams
may be affected as well. A call to dribble
with no
arguments undoes these side effects.
In the ``recursive’’ model, by contrast, a call to
dribble
with a pathname argument creates a new interactive
command loop and calls it recursively. This new command loop is just
like an ordinary read-eval-print loop except that it also echoes the
interaction to the dribble file. A call to dribble
with no
arguments does a throw
that exits the recursive command
loop and returns to the original caller of dribble
with an
argument.
The two models may be distinguished by this test case:
(progn (dribble "basketball")
(print "Larry")
(dribble)
(princ "Bird"))
If this form is input to the Lisp top level, in either model a
newline (provided by the function print
) and the words
Larry Bird
will be printed to the standard output. The
redirecting dribble model will additionally print all but the word
Bird
to a file named basketball
.
By contrast, the recursive dribble model will enter a recursive
command loop and not print anything until (dribble)
is
executed from within the new interactive command loop. At that time the
file named basketball
will be closed, and then execution of
the progn
form will be resumed. A newline and
``Larry
’’ (note the trailing space) will be printed to the
standard output, and then the call (dribble)
may complain
that there is no active dribble file. Once this error is resolved, the
word Bird
may be printed to the standard output.
Here is a slightly different test case:
(dribble "baby-food")
(progn (print "Mashed banana")
(dribble)
(princ "and cream of rice"))
If this form is input to the Lisp top level, in the redirecting model
a newline and the words Mashed banana and cream of rice
will be printed to the standard output and all but the words
and cream of rice
will be sent to a file named
baby-food
.
The recursive model will direct exactly the same output to the file
named baby-food
but will never print the words
and cream of rice
to the standard output because the call
(dribble)
does not return normally; it throws.
The redirecting model may be intuitively more appealing to some. The
recursive model, however, may be more robust; it carefully limits the
extent of the dribble operation and disables dribbling if a throw of any
kind occurs. The vote by X3J13 was an explicit decision not to decide
which model to use. Users are advised to call dribble
only
interactively, at top level.
[Function]
apropos
string
&optional
package
apropos-list
string
&optional
package
(apropos
string
)
tries
to find all available symbols whose print names contain string
as a substring. (A symbol may be supplied for the string, in
which case the print name of the symbol is used.) Whenever
apropos
finds a symbol, it prints out the symbol’s name; in
addition, information about the function definition and dynamic value of
the symbol, if any, is printed. If package is specified and not
nil
, then only symbols available in that package are
examined; otherwise ``all’’ packages are searched, as if by
do-all-symbols
. Because a symbol may be available by way of
more than one inheritance path, apropos
may print
information about the same symbol more than once. The information is
printed to the stream that is the value of
*standard-output*
. apropos
returns no values
(that is, it returns what the expression (values)
returns:
zero values).
apropos-list
performs the same search that
apropos
does but prints nothing. It returns a list of the
symbols whose print names contain string as a substring.
Next: Environment Inquiries
Up: Miscellaneous Features
Previous: Documentation
AI.Repository@cs.cmu.edu