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

trace



A long time ago Jonathan asked what people did to trace self-recursive calls
to FACT when FACT is defined using the (DEFINE (FACT ...) ...) syntax.  It
seems to me there are three obvious implementations of the trace facility,
with three distinct semantics:

1.  Trace the variable.  That is, (TRACE FACT) is a special form that turns
into something like (SET! FACT (MAKE-TRACED FACT)).  This is how most
implementations seem to do it, though in some of them (e.g. MacScheme) TRACE
is a procedure and you have to say (TRACE 'FACT).

The disadvantage is that the self-recursive calls are not traced.

2.  Trace the closure.  That is, TRACE is a procedure and (TRACE FACT)
clobbers some field(s) of the data structure used to represent the procedure
stored in the variable FACT.

This will trace the self-recursive calls.  The disadvantage is that it also
will trace calls to FOO where FOO is any variable that happens to hold the
same closure as is stored in the variable FACT.

3.  Trace the code.  That is, TRACE is a procedure and (TRACE FACT)
clobbers the first instruction(s) of the code portion of the closure.

This will trace the self-recursive calls.  The disadvantage is that it also
will trace calls to any procedure obtained by closing the same lambda
expression.  In fact, the precise semantics of this option is likely to
depend upon small details of an optimizing compiler.

It seems to me that implementations 1 and 2 are the most reasonable.  Perhaps
users should be able to choose between the two.

Thanks to Norman Adams for his criticisms of the three implementations.

Peace, Will Clinger