[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Fast or slow linkage re TRACE, what to put in specs?
- To: COMMON-LISP%SU-AI@SCORE
- Subject: Fast or slow linkage re TRACE, what to put in specs?
- From: Rem@IMSSS
- Date: Fri, 12 Oct 1984 01:23:00 -0000
(From a longstanding LISP user: SU-1.6, UCI-LISP, MacLISP <my favorite>,
USLISP, PSL; but newcomer to Common LISP.
Regarding what can be traced and what can be open-coded or otherwise
modified so it can't be traced.)
Date: Thu, 11 Oct 1984 22:47 EDT
From: Skef Wholey <Wholey@CMU-CS-C.ARPA>
Is it alright for the writer of a "module" to [use fast linkage
when a function in the module calls another in the same module]?
Why should the random user who wants to trace Print have any
reason to believe that the writer of the code supplied to him used
that function? Sounds like information-hiding to me. Last I
checked, that was suppsoed to be a good thing.
I agree. When the a particular function-call within to a module is not
a documented one (thus the user doesn't have any reason to expect a
particular kind of linkage nor even the function call at all), and
when using fast (untraceable) linkage makes the code run faster or
take up less space, and when full (traceable) linkage is no longer
needed for debugging because this module is fully tested and being
distributed to customers, it's completely reasonable (fair,
permissible) to compile that function-call using fast linkage. If
somebody later wants to debug that module (a previously undiscovered
bug crops up, or modifications are desired), the module can be
recompiled using slow linkage during the debugging period, and then
restored to fast linkage when it's back in production form. <Opinion>
Partition the set of Common Lisp functions into three classes:
1. Those that may be open-coded.
2. Those that may either be open-coded or left alone.
3. Those that should never be open-coded.
I agree providing you're referring only to calls from user code. Calls
within system code may be fast-coded as pre my previous paragraph.
The user should have reason to expect calls from that user's code to a
certain class of functions (documented in class 3 above) will always
be slow-coded (traceable) when called from the user's own code. The
user should also be provided a facility to selectively modify the
behaviour of the compiler when desired so that calls from the user's
newly-compiled code to certain other specifically named functions will
also be slow-coded.
Information-hiding is a good thing, but a better thing about Lisp
is that it has usually provided a way around it, so that people
can get work done. I've used the Lisp Machine Inspector to
"unlock" a package to hack some symbols in that package. I didn't
need to read any documentation or source code.
This is a good alternative to tracing when you don't have the source
for somebody else's module, or you don't have time or desire to
recompile it, or it works fine with slow linkage but there's a bug in
open coding, etc. It may be too soon in the state of the art to
specify every Common-LISP implementation should have an inspector, but
such facility should perhaps be described and encouraged in the manual.
There's no real reason to treat compiled code as a black box and
TRACE as the only tool for finding things out about the contents
of that box. Contrary to what Hedrick says, this IS Lisp.
But TRACE is a good first measure to handle 90% of the problems.
Beyond simple TRACE, a PAUSE-TRACE should be available which prints
the arguments like TRACE, but then asks if the user wants (after
seeing arguments) to go into a BREAK (read-eval-print) loop before
executing the called function; then after printing the result asks
again if the user wants to go into a BREAK before returning. I think
Common LISP ought to have TRACE with break-before and break-after more
than it should have half the random cruft currently in the specs. <Out
on a limb opinion>
Date: Thu, 11 Oct 1984 23:04 EDT
From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>
Some implementations are going to use all sorts of tricks
to get full efficiency, and some of these may interfere with
tracing. I think that the right attitude is that interpreted code
definitely should be traceable and anything else you get is gravy.
I agree. Calls from or to interpreted code always should be traceable
(but I don't think anybody has an implementation where this is
violated except where an FEXPR or MACRO is being called and the trace
package can't handle it, so this isn't the disputed point). We need to
think about how much gravy, since it truly is useful to trace compiled
calls from code that is compiled either because it's too slow to debug
interpreted or we thought it worked and now we see it really doesn't.
It's a royal pain to have to retreat to interpreted code just because
we want to trace a call. Therefore we really need some "gravy". The
question is how much and how to document it.
So it seems to me that each implementation should do the best it
can on this, and should document which things you can trace and
which you can't. Do we need to say anything more about this?
Maybe. Do we make it total caveat emptor, with each implementation
required only to document what it has done, or do we put some
constraints on implementation to force a minimal amount of "gravy"
across all systems. Since debugging is the essence of LISP, and all
customers of barebones Common LISP will expect the ability to debug
software they write, I don't think total caveat emptor is the way to go.