[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Issue: TRACE-FUNCTION-ONLY (Version 4)



(Font Note: UPPERCASE indicates bold, _this_ indicates italic)

--------------------------------------------------------------------------------


Issue:         TRACE-CLOS

References:    trace macro pp. 440-441
	       TRACE-ARGUMENT-FORMAT-OPTIONS
	       SETF-CLOS

Category:      MODIFICATION

Edit history:  Version 1, 21-Oct-87 Kempf
	       Version 2, 27-Oct-87 Kempf
	       Version 3, 28-Oct-87 Kempf
	       Version 4, 30-Oct-87 Kempf

Problem description:

With the addition of the Common Lisp Object System, there is no
command language level way to trace individual method execution.
The TRACE macro, as currently specified in Common Lisp, allows
only tracing of globally defined functions through their names.
Since a generic function name may have several executable methods,
users need some way to specify that they would like invocation of particular
methods to be traced, rather than invocation of the entire generic
function.  In addition, the current specification of TRACE does not 
allow tracing of functions associated with SETF "methods", of macro 
functions,  nor of lexically defined functions or functions invoked via. their
function definition objects.  While this proposal does not attempt 
to address the latter two problems, since identification and/or tracing of these
is likely to be implementation dependent, it does leave 
open the option for those implementations which can arrange it. 

Proposal (TRACE-CLOS::TRACE-FUNCTION-SPECIFICATION)

TRACE _{function-spec}*_  _[Macro]_

UNTRACE _{function-spec}*_	_[Macro]_

Invoking TRACE with a function specification causes the function specified
to be traced. Henceforth, whenever the specified function is invoked,
information about the call, the arguments passed, and the returned
values, if any, will be printed to the stream that is the value of
*TRACE-OUTPUT*. UNTRACE undoes any tracing. Calling TRACE without 
any arguments prints a list of currently traced executable entities, calling
UNTRACE without any arguments causes tracing to be undone for
all currently traced entities.

A _function_spec_ is either a symbol naming a function (i.e. a
symbol whose global function cell is bound to a function definition
object, or to which the application of MACRO-FUNCTION will return
a function definition object) or a list whose first element indicates
what kind of funcallable object is to be traced and whose tail indicates
which particular function should be traced. The complete set of
function specifications will necessarily be implementation dependent; however,
every implementation is required to support the following:

 	_symbol_-Invocations of the function or macrofunction named by
 	         _symbol_ via. _symbol_ as a global name are traced.

 	(METHOD _generic-function-name-specification_
                 _{method-qualifiers}_* 
 	        _parameter-specializer-name-list_
         )
 	If the method whose parameter specializer list, generic function
 	name specification, and method qualifiers are listed is tracable,
 	then invocations through the generic function name specification 
 	will be traced.

 	(SETF _symbol_)-If the SETF function having the name specification
 	is tracable, it will be traced (see proposal SETF-CLOS for
 	more information on SETF name specifications).

Implementations are encouraged to provide for tracing of as many
funcallable objects as possible.

Note that this proposal does not change the current Common Lisp
specification in the area of "open-coded" functions. In particular,
implementations need not arrange for tracing of "open-coded" functions,
including compiled self calls which do not go through the symbol-function
cell. 

In the case of tracing macro expansions, the trace is of the call to
the macroexpansion funtion and not of executing the return code. Thus the
trace function need only print the calling form arguments and the
expanded form being returned. As with "open-coded" functions, implementations 
which memoize the expansion code are under no obligation to report trace 
information once the macro code has been memoized. The example section 
provides an example of an interactive session tracing a macro expansion.


Example: 

1 [LISP] >    (defmacro test-trace (arg)
1 [LISP] >      `(format T "~S~%" ,arg)
1 [LISP] >    )
TEST-TRACE
2 [LISP] >    (trace test-trace)
((MACROFUNCTION TEST-TRACE))
3 [LISP] >  (test-trace 'foo)
Entering macrofunction TEST-TRACE with arguments:
   (QUOTE FOO)
Leaving macrofunction TEST-TRACE with return values:
   (FORMAT T "~S~%" (QUOTE FOO))
FOO
4 [LISP] >

Rationale:

Adoption of the Common Lisp Object System will require the availability
of debugging information on individual methods. Adoption of the
SETF-CLOS proposal will require means of tracing SETF functions. It is
also not possible to easily trace either SETF functions or macrofunctions
today.

This proposal does not address a number of additional features of TRACE
(adding breakpoints, system hooks for extensible debugging, etc.) which
may be included in other proposals. In addition, the proposal recongnizes
that TRACE is part of the enviroment, and that future versions of the
Common Lisp standard may want to specify it as such. Different criteria 
may therefore apply for evaluating compliance, for example, stand alone
Common Lisp applications may not require environmental features like
TRACE which are primarily included for program development, and their
compliance to the standard should therefore not be judged on the basis
of whether or not they implement such environmental features.

Current practice:

There is currently no way which is standard across all implementations 
to trace SETF functions, aside from macroexpanding a SETF form and using 
the resulting name in a TRACE macro invocation. There is currently no way 
which is standardized across all implementations to trace macroexpansion
functions when they are invoked through their global names, except through
complicated use of *MACROEXPAND-HOOK*.

Adoption Cost:

The proposed syntax is upwardly compatible with the current Common Lisp
syntax. It will require the addition of function specification parsing
and wrapper code to trace SETF function executions and macrofunction
executions. When the Common Lisp Object System is fully implemented,
wrapper code for tracing method execution will also be required.

Cost of non-adoption:

Implementations will provide this functionality in varying forms and
to varying degrees, thus making it harder for users to move between
one Common Lisp system and another. Some implementations may choose
not to provide the functionality, in which case users will suffer.

Benefits:

Allow programmers to obtain information on individual method
invocations, and on SETF function and macrofunction invocations
in a uniform way across all implementations.

Conversion Cost:

Minor re-write of the TRACE and UNTRACE macros, and supporting wrapper
generating functions. Some implementations which have made extensions
to TRACE will need to accommodate those extensions with the additional
syntax.