Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Debugging mispellings?

6 views
Skip to first unread message

Barry Margolin

unread,
Oct 10, 1997, 3:00:00 AM10/10/97
to

In article <61ml0s$fng$1...@mycroft.westnet.com>,
Lawrence Troxler <l...@westnet.com> wrote:
>In my recent dabblings with Common Lisp, I've noticed that simple
>mispellings of symbols seem to be not always easy to catch, as they would
>be with C, for example. For example, I just spent 10 minutes debugging an
>unbound-variable message, only to find out that I had mispelled it in the
>let-binding. Is this just due to my lack of experience with lisp? Does
>this get easier with time? In C, mis-spelled variables are trivial to find
>and fix (a matter of seconds), while with Lisp, I am finding that I often
>need many minutes to find these problems. I imagine that the
>difficulty is that Lisp is a dynamic language, whereas with C, symbol
>references are always static, and hence are trivial to debug.

Could you give an example of the kinds of mistakes you're running into?
Most variable misspelling will won't result in a warning from good
compilers. For instance, if you do:

(defun broken-function (varible)
(print variable))

you should get two warnings: one that VARIBLE is bound but never used, and
another that VARIABLE is being presumed SPECIAL. Or if you do:

(defun my-print (thing half-radix)
(let ((*print-bas* (* half-radix 2)))
(print thing)))

you should get a warning that *PRINT-BAS* is bound but not used.

--
Barry Margolin, bar...@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
Support the anti-spam movement; see <http://www.cauce.org/>
Please don't send technical questions directly to me, post them to newsgroups.

Lawrence Troxler

unread,
Oct 11, 1997, 3:00:00 AM10/11/97
to

In my recent dabblings with Common Lisp, I've noticed that simple
mispellings of symbols seem to be not always easy to catch, as they would
be with C, for example. For example, I just spent 10 minutes debugging an
unbound-variable message, only to find out that I had mispelled it in the
let-binding. Is this just due to my lack of experience with lisp? Does
this get easier with time? In C, mis-spelled variables are trivial to find
and fix (a matter of seconds), while with Lisp, I am finding that I often
need many minutes to find these problems. I imagine that the
difficulty is that Lisp is a dynamic language, whereas with C, symbol
references are always static, and hence are trivial to debug.

Well, in any case, I'm not writing to flame Lisp, but to ask for guidance
in
how to troubleshoot these cases a little faster.

Larry

--
-- Larry Troxler -- l...@westnet.com -- Patterson, NY USA --

William Paul Vrotney

unread,
Oct 11, 1997, 3:00:00 AM10/11/97
to

In article <61ml0s$fng$1...@mycroft.westnet.com> Lawrence Troxler
<l...@westnet.com> writes:

You are probably comparing apples to organges. That is to say I suspect
that you are running the Lisp code with the Lisp interpreter and of course
with C code you *must* compile it. The C compiler serves as a batch code
analyzer. If you compile the Lisp code most good Lisp compilers will give
you warnings. For example if we intentionally misspell a variable in a
program using Allegro CL

(defun faa (x) (let ((cay 5)) (+ x cat)))
FAA

First interpreted

(faa 5)
Error: Attempt to take the value of the unbound symbol CAT

then compile (more like C)

(compile 'faa)
Warning: Symbol CAT declared special
Warning: variable CAY is never used

In many Common Lisps you can also turn on/off various kinds of compiler
warnings. See your CL manual. There are also tools for automating the
recompiling of Lisp functions that change, code analysis tools and Emacs
Lisp shells that help with debugging. See the Lisp FAQ.

Also note that if you are an Emacs user there are tools for eliminating
misspellings. A very simple one is DABBREV-EXPAND bound to M-/, which not
only helps spell a previously typed variable the same way but even
eliminates having to retype it.

Your intuition is partially correct in that Lisp being a dynamic language is
related to "run time surprises", however many of us who program in both C
and Lisp feel that the benefits of a dynamic language far outweigh the
uncertainty of "run time surprises". Furthermore when one starts writing C
and C++ programs that needs to create and delete complex run time data, one
still gets "run time surprises", only they are frequently harder to debug
than in Lisp and in some sense more fatal. In Common Lisp there are clean
ways of dealing with "run time surprises" programmatically using the Common
Lisp *condition system*.

I guarantee you that after you learn Lisp and the Lisp development tools
well, your overall development time will be dramatically reduced over
development time using C even if you are expert with GDB. The problem of
misspelled variables should become negligible.

--

William P. Vrotney - vro...@netcom.com

Emergent Technologies

unread,
Oct 11, 1997, 3:00:00 AM10/11/97
to

For the (LMI) Lisp machine, one of us (Pace or I) wrote a package DWIM
to deal with misspelled symbols. Rather than interning the new
symbol, it did a quick search for similar symbol names within the
package and offered a proceed option to use that one instead.

Ken Tilton

unread,
Oct 13, 1997, 3:00:00 AM10/13/97
to

Lawrence Troxler wrote:
>
> In my recent dabblings with Common Lisp, I've noticed that simple
> mispellings of symbols seem to be not always easy to catch, as they would
> be with C, for example. For example, I just spent 10 minutes debugging an
> unbound-variable message, only to find out that I had mispelled it in the
> let-binding. Is this just due to my lack of experience with lisp? Does
> this get easier with time?

It might be just lack of experience, though I am not sure I follow your
example. Can you post some erroneous code that stumped you for a while?

My compiler (Mac Common Lisp) tells me if I misspell an lvar or function
argument (and even if I do not /use/ one, which might mean I referred to
a valid variable when I meant to refer to something else). If I code:

(let ((iten (find-item ....)))
(format t "The item is ~s" item))

...my compiler squawks about "item", same as in C (except when I hit
Enter, not when I compile the entire source file. <g> Did you not get a
message until runtime?

My bottom line answer is I have written a ton of C and do appreciate the
language, but (1) Lisp is not harder to debug than C in any way, (2) it
is easier to debug in many ways.

Just thought of one C debugging advantage: source debugging. But I do
not like source debugging except for certain kinds of bugs.

Cheers,

Ken

David B. Lamkins

unread,
Oct 13, 1997, 3:00:00 AM10/13/97
to

On Fri, Oct 10, 1997 6:33 PM, Lawrence Troxler <mailto:l...@westnet.com>

wrote:
>In my recent dabblings with Common Lisp, I've noticed that simple
>mispellings of symbols seem to be not always easy to catch, as they would
>be with C, for example. For example, I just spent 10 minutes debugging an
>unbound-variable message, only to find out that I had mispelled it in the
>let-binding. Is this just due to my lack of experience with lisp? Does
>this get easier with time? In C, mis-spelled variables are trivial to find
>and fix (a matter of seconds), while with Lisp, I am finding that I often
>need many minutes to find these problems. I imagine that the
>difficulty is that Lisp is a dynamic language, whereas with C, symbol
>references are always static, and hence are trivial to debug.
>
>Well, in any case, I'm not writing to flame Lisp, but to ask for guidance
>in
>how to troubleshoot these cases a little faster.
>

You may be able to coax some more informative messages out of your compiler
(what is it, BTW?) by evaluating this at the start of your session:

(declaim (optimize (debug 3) (safety 3) (compilation-speed 0))

Dave

? the platypus {aka David Formosa}

unread,
Oct 13, 1997, 3:00:00 AM10/13/97
to

In <61ml0s$fng$1...@mycroft.westnet.com> Lawrence Troxler <l...@westnet.com> writes:

>In my recent dabblings with Common Lisp, I've noticed that simple
>mispellings of symbols seem to be not always easy to catch, as they would
>be with C, for example.

Partly this is because of your lack of exprence with lisp. I tend
(because of my condtion) to add meany meany spelling errors and have had
no great problem tracking them down.

Hopefully with a bit more exprence your will be able to trace down
spelling errors with the best of them.

> For example, I just spent 10 minutes debugging an
>unbound-variable message, only to find out that I had mispelled it in the
>let-binding.

This is a typicl problem annd would have been the first thing that I would
have looked out. Don't worry we all had these problems when we started.

--
Please excuse my spelling as I suffer from agraphia see the url in my header.
Never trust a country with more peaple then sheep. Buy easter bilbies.
Save the ABC Is $0.08 per day too much to pay? ex-net.scum and proud
I'm sorry but I just don't consider 'because its yucky' a convincing argument

Rainer Joswig

unread,
Oct 14, 1997, 3:00:00 AM10/14/97
to

In article <3442BF...@bway.net>, ti...@bway.net wrote:

> My compiler (Mac Common Lisp) tells me if I misspell an lvar or function
> argument (and even if I do not /use/ one, which might mean I referred to
> a valid variable when I meant to refer to something else). If I code:
>
> (let ((iten (find-item ....)))
> (format t "The item is ~s" item))
>
> ...my compiler squawks about "item", same as in C (except when I hit
> Enter, not when I compile the entire source file. <g> Did you not get a
> message until runtime?

For me it works even when I hit enter.

;Compiler warnings :
; Undeclared free variable ITEM, in an anonymous lambda form.
; Unused lexical variable ITEN, in an anonymous lambda form.
> Error: Unbound variable: ITEM

> My bottom line answer is I have written a ton of C and do appreciate the
> language, but (1) Lisp is not harder to debug than C in any way,

Sounds like a C problem

> (2) it
> is easier to debug in many ways.

Hmm, Common Lisp code with Macros or Macros generating Macros
is notoriously difficult to debug. Often you don't have an
idea what generated your code or what your current stack frame
corresponds to. Without a good idea about Common Lisp and
the application it is completely unthinkable to debug some
of the advanced programs. There is no real chance for
source line debugging.

--
http://www.lavielle.com/~joswig/

Marc Wachowitz

unread,
Oct 14, 1997, 3:00:00 AM10/14/97
to

jos...@lavielle.com (Rainer Joswig) wrote:
> Hmm, Common Lisp code with Macros or Macros generating Macros
> is notoriously difficult to debug. Often you don't have an
> idea what generated your code or what your current stack frame
> corresponds to. [...] There is no real chance for source line debugging.

Clearly, a simple line-for-line correspondence between target code
and source code just isn't going to be as meaningful as in languages
without any macros - even C's rather primitive preprocessor can make
this quite complicated for a naive reader of the result. Yet, a Common
Lisp implementation could do quite a lot to cover most typical cases
(whether it's worth the implementation effort is another question).

Even though a macro can in principle generate code where fragments
don't correlate with the source in any way which could be described
very clearly (e.g. doing complex things with the string representation
of the involved symbols, and other hairy stuff with the CONS cells),
that's rare, and an implementation surely could associate information
about the origin and transformation-history of program source code
with the related objects, as long as there isn't too much semantically
meaningless reuse of identical CONS cells between otherwise unrelated
parts of the program (which is unlikely in normal development).

I expect that some heuristics for typical transformations done in macros
(e.g. building new symbols from existing symbols, list transformations
and backquote, GENSYM etc.), together with useful presentation styles
for such patterns, could deliver sufficiently understandable descriptions
of the target code's genesis - preferably via some kind of live hyper-
text which can "time-travel" through the various translation phases.

(As extreme measure, one could also record and partially replay an exact
trace of some or all calls to macro functions, but that's probably too
much stuff to keep around, and more than one would usually want to know ;-)

For some interesting ideas about hygienic macros, where such things
are relatively simple, look for SYNTAX-CASE in the Scheme repository
(this is a macro facility with the full power of the language - not
just the more restricted pattern language which has been described
in R4RS).

-- Marc Wachowitz <m...@ipx2.rz.uni-mannheim.de>

Erik Naggum

unread,
Oct 14, 1997, 3:00:00 AM10/14/97
to

* Rainer Joswig

| Hmm, Common Lisp code with Macros or Macros generating Macros is
| notoriously difficult to debug. Often you don't have an idea what
| generated your code or what your current stack frame corresponds to.
| Without a good idea about Common Lisp and the application it is
| completely unthinkable to debug some of the advanced programs. There is

| no real chance for source line debugging.

I would have thought that an (optimize (debug 3)) declaration in effect
would have made such information available even in a compile-only Common
Lisp, but I think I prefer having an interpreter available when debugging,
although there is still a problem when running macro expansion functions.
`step' is source line debugging for me.

the only time I have missed source line debugging is when finding the rare
compiler bug, not when finding my own bugs.

#\Erik
--
if you think this year is "97", _you_ are not "year 2000 compliant".

see http://www.naggum.no/emacs/ for Emacs-20-related material.

Rainer Joswig

unread,
Oct 16, 1997, 3:00:00 AM10/16/97
to

In article <6207ko$5ah$1...@trumpet.uni-mannheim.de>,
m...@ipx2.rz.uni-mannheim.de (Marc Wachowitz) wrote:

> Clearly, a simple line-for-line correspondence between target code
> and source code just isn't going to be as meaningful as in languages
> without any macros - even C's rather primitive preprocessor can make
> this quite complicated for a naive reader of the result. Yet, a Common
> Lisp implementation could do quite a lot to cover most typical cases
> (whether it's worth the implementation effort is another question).

The mythical "sufficiently smart Lisp"? Haven't seen one yet
(well the Lispm comes close, but is much to complicated).

I have yet to find a Lisp being able to effectively debug
the perverse cases.

Have a look at the CL-HTTP code.

CLOS + Macros + Inlining + Local Macros.

>
> Even though a macro can in principle generate code where fragments
> don't correlate with the source in any way which could be described
> very clearly (e.g. doing complex things with the string representation
> of the involved symbols, and other hairy stuff with the CONS cells),
> that's rare, and an implementation surely could associate information
> about the origin and transformation-history of program source code
> with the related objects, as long as there isn't too much semantically
> meaningless reuse of identical CONS cells between otherwise unrelated
> parts of the program (which is unlikely in normal development).


* (in-package :http)
#<The HTTP package, 2503/3130 internal, 278/525 external>

* (macroexpand '(define-standard-directory-export-types (:html :text :lisp
:image :audio :video :application :world)))

This short expression gives me:


(PROGN
(PROGN
(DEFINE-DIRECTORY-EXPORT-TYPE :DIRECTORY
(:HTML :TEXT :LISP :IMAGE :AUDIO :VIDEO
:APPLICATION :WORLD))
(DEFINE-DIRECTORY-EXPORT-TYPE :DIRECTORY-HIERARCHY
(:HTML :TEXT :LISP :IMAGE :AUDIO :VIDEO
:APPLICATION :WORLD)
:DIRECTORIES
T)
(DEFMETHOD EXPORT-URL
:AROUND
((URL HTTP-PATH) (TRANSLATION (EQL :DIRECTORY)) &REST ARGS)
(DESTRUCTURING-BIND
(&KEY RECURSIVE-P &ALLOW-OTHER-KEYS)
ARGS
(IF RECURSIVE-P
(APPLY #'EXPORT-URL URL :DIRECTORY-HIERARCHY ARGS)
(CALL-NEXT-METHOD)))))
(PROGN
(DEFINE-DIRECTORY-EXPORT-TYPE :HTML-DIRECTORY (:HTML))
(DEFINE-DIRECTORY-EXPORT-TYPE :HTML-DIRECTORY-HIERARCHY
(:HTML)
:DIRECTORIES
T)
(DEFMETHOD EXPORT-URL
:AROUND
((URL HTTP-PATH) (TRANSLATION (EQL :HTML-DIRECTORY)) &REST ARGS)
(DESTRUCTURING-BIND
(&KEY RECURSIVE-P &ALLOW-OTHER-KEYS)
ARGS
(IF RECURSIVE-P
(APPLY #'EXPORT-URL URL :HTML-DIRECTORY-HIERARCHY ARGS)
(CALL-NEXT-METHOD)))))
(PROGN
(DEFINE-DIRECTORY-EXPORT-TYPE :TEXT-DIRECTORY (:TEXT))
(DEFINE-DIRECTORY-EXPORT-TYPE :TEXT-DIRECTORY-HIERARCHY
(:TEXT)
:DIRECTORIES
T)
(DEFMETHOD EXPORT-URL
:AROUND
((URL HTTP-PATH) (TRANSLATION (EQL :TEXT-DIRECTORY)) &REST ARGS)
(DESTRUCTURING-BIND
(&KEY RECURSIVE-P &ALLOW-OTHER-KEYS)
ARGS
(IF RECURSIVE-P
(APPLY #'EXPORT-URL URL :TEXT-DIRECTORY-HIERARCHY ARGS)
(CALL-NEXT-METHOD)))))
(PROGN
(DEFINE-DIRECTORY-EXPORT-TYPE :LISP-DIRECTORY (:LISP))
(DEFINE-DIRECTORY-EXPORT-TYPE :LISP-DIRECTORY-HIERARCHY
(:LISP)
:DIRECTORIES
T)
(DEFMETHOD EXPORT-URL
:AROUND
((URL HTTP-PATH) (TRANSLATION (EQL :LISP-DIRECTORY)) &REST ARGS)
(DESTRUCTURING-BIND
(&KEY RECURSIVE-P &ALLOW-OTHER-KEYS)
ARGS
(IF RECURSIVE-P
(APPLY #'EXPORT-URL URL :LISP-DIRECTORY-HIERARCHY ARGS)
(CALL-NEXT-METHOD)))))
(PROGN
(DEFINE-DIRECTORY-EXPORT-TYPE :IMAGE-DIRECTORY (:IMAGE))
(DEFINE-DIRECTORY-EXPORT-TYPE :IMAGE-DIRECTORY-HIERARCHY
(:IMAGE)
:DIRECTORIES
T)
(DEFMETHOD EXPORT-URL
:AROUND
((URL HTTP-PATH) (TRANSLATION (EQL :IMAGE-DIRECTORY)) &REST ARGS)
(DESTRUCTURING-BIND
(&KEY RECURSIVE-P &ALLOW-OTHER-KEYS)
ARGS
(IF RECURSIVE-P
(APPLY #'EXPORT-URL URL :IMAGE-DIRECTORY-HIERARCHY ARGS)
(CALL-NEXT-METHOD)))))
(PROGN
(DEFINE-DIRECTORY-EXPORT-TYPE :AUDIO-DIRECTORY (:AUDIO))
(DEFINE-DIRECTORY-EXPORT-TYPE :AUDIO-DIRECTORY-HIERARCHY
(:AUDIO)
:DIRECTORIES
T)
(DEFMETHOD EXPORT-URL
:AROUND
((URL HTTP-PATH) (TRANSLATION (EQL :AUDIO-DIRECTORY)) &REST ARGS)
(DESTRUCTURING-BIND
(&KEY RECURSIVE-P &ALLOW-OTHER-KEYS)
ARGS
(IF RECURSIVE-P
(APPLY #'EXPORT-URL URL :AUDIO-DIRECTORY-HIERARCHY ARGS)
(CALL-NEXT-METHOD)))))
(PROGN
(DEFINE-DIRECTORY-EXPORT-TYPE :VIDEO-DIRECTORY (:VIDEO))
(DEFINE-DIRECTORY-EXPORT-TYPE :VIDEO-DIRECTORY-HIERARCHY
(:VIDEO)
:DIRECTORIES
T)
(DEFMETHOD EXPORT-URL
:AROUND
((URL HTTP-PATH) (TRANSLATION (EQL :VIDEO-DIRECTORY)) &REST ARGS)
(DESTRUCTURING-BIND
(&KEY RECURSIVE-P &ALLOW-OTHER-KEYS)
ARGS
(IF RECURSIVE-P
(APPLY #'EXPORT-URL URL :VIDEO-DIRECTORY-HIERARCHY ARGS)
(CALL-NEXT-METHOD)))))
(PROGN
(DEFINE-DIRECTORY-EXPORT-TYPE :APPLICATION-DIRECTORY (:APPLICATION))
(DEFINE-DIRECTORY-EXPORT-TYPE :APPLICATION-DIRECTORY-HIERARCHY
(:APPLICATION)
:DIRECTORIES
T)
(DEFMETHOD EXPORT-URL
:AROUND
((URL HTTP-PATH) (TRANSLATION (EQL :APPLICATION-DIRECTORY)) &REST
ARGS)
(DESTRUCTURING-BIND
(&KEY RECURSIVE-P &ALLOW-OTHER-KEYS)
ARGS
(IF RECURSIVE-P
(APPLY #'EXPORT-URL
URL
:APPLICATION-DIRECTORY-HIERARCHY
ARGS)
(CALL-NEXT-METHOD)))))
(PROGN
(DEFINE-DIRECTORY-EXPORT-TYPE :WORLD-DIRECTORY (:WORLD))
(DEFINE-DIRECTORY-EXPORT-TYPE :WORLD-DIRECTORY-HIERARCHY
(:WORLD)
:DIRECTORIES
T)
(DEFMETHOD EXPORT-URL
:AROUND
((URL HTTP-PATH) (TRANSLATION (EQL :WORLD-DIRECTORY)) &REST ARGS)
(DESTRUCTURING-BIND
(&KEY RECURSIVE-P &ALLOW-OTHER-KEYS)
ARGS
(IF RECURSIVE-P
(APPLY #'EXPORT-URL URL :WORLD-DIRECTORY-HIERARCHY ARGS)
(CALL-NEXT-METHOD))))))
T


Then expand the DEFINE-DIRECTORY-EXPORT-TYPE forms. One example:

* (macroexpand '(DEFINE-DIRECTORY-EXPORT-TYPE :WORLD-DIRECTORY (:WORLD)))


(PROGN
(DEFMETHOD EXPORT-URL
((URL HTTP-PATH) (TRANSLATION (EQL :WORLD-DIRECTORY)) &REST ARGS)
(DESTRUCTURING-BIND
(&KEY PATHNAME RECACHE
(IMMEDIATE-EXPORT (NOT (EQL *AUTO-EXPORT* :ON-DEMAND)))
CHARACTER-SET &ALLOW-OTHER-KEYS)
ARGS
(COND
(PATHNAME
(SETF (TRANSLATED-PATHNAME URL)
(MAKE-DIRECTORY (TRANSLATED-PATHNAME PATHNAME))))
(T
(ERROR
"No PATHNAME was provided while exporting the URL, ~S,
with translation, ~S"
URL
TRANSLATION)))
(SETF (TRANSLATION-METHOD URL)
:WORLD-DIRECTORY
(CHARACTER-SET URL)
CHARACTER-SET)
(WHEN IMMEDIATE-EXPORT
(LET ((URL-NAME-STRING (NAME-STRING URL)))
(%%MAP-EXPORT-DIRECTORY
(:URL URL :DATA-TYPES (:WORLD) :DIR-OPTIONS (:FILES)
:DIRECTORIES-P NIL)
(COND ((PATHNAME-DIRECTORY-P TRANSLATED) NIL)
((AND (OR IMMEDIATE-EXPORT RECACHE)
(EXPORT-PATHNAME-P TRANSLATED))
(%EXPORT-PATHNAME TRANSLATED
URL-NAME-STRING
ARGS
RECACHE))))))
URL))
(DEFMETHOD WRITE-DOCUMENT-HEADERS
((URL HTTP-PATH) (TRANSLATION (EQL :WORLD-DIRECTORY)) STREAM)
(%WRITE-DOCUMENT-HEADERS-NO-PATHNAME URL :HTML STREAM NIL))
(DEFMETHOD WRITE-DOCUMENT
((URL HTTP-PATH) (TRANSLATION (EQL :WORLD-DIRECTORY)) STREAM)
(FLET ((INTERN-PATH-URL (PATH URL)
(INTERN-PATHNAME-AS-URL-INFERIOR PATH
URL
:IF-DOES-NOT-EXIST
:CREATE))
(ANCHOR-TEXT (URL PATHNAME DIRECTORY-FILE-P)
(COND (DIRECTORY-FILE-P NIL)
(T
(WITH-VALUE-CACHED (URL :DIRECTORY-STRING)
(LET ((NAME (OBJECT URL))
(TYPE
(PATHNAME-TYPE PATHNAME))
(VERSION
(PATHNAME-VERSION
PATHNAME)))
(DECLARE
(DYNAMIC-EXTENT NAME))
(TYPECASE VERSION
((OR KEYWORD NULL)
(CONCATENATE 'STRING
NAME
"."
TYPE))
(T
(CONCATENATE 'STRING
NAME
"."
TYPE
"."

(WRITE-TO-STRING
VERSION
:BASE
10
:ESCAPE
NIL)))))))))
(INCLUSION-PREDICATE (PATHNAME)
(%MAKE-DATA-TYPE-PATHNAME-PREDICATE PATHNAME
(:WORLD)
NIL)))
(DECLARE
(DYNAMIC-EXTENT #'INTERN-PATH-URL #'ANCHOR-TEXT
#'INCLUSION-PREDICATE))
(WITH-CONDITIONAL-GET-RESPONSE
(STREAM :HTML :EXPIRES (EXPIRATION-UNIVERSAL-TIME URL) :LOCATION
URL :CACHE-CONTROL (RESPONSE-CACHE-CONTROL-DIRECTIVES URL)
:CONTENT-LANGUAGE (LANGUAGES URL))
(WRITE-DIRECTORY-LISTING URL
STREAM
#'INCLUSION-PREDICATE
#'INTERN-PATH-URL
#'ANCHOR-TEXT
#'PATH-DIRECTORY-STRING
NIL))))
(DEFMETHOD %UNEXPORT-DIRECTORY
((URL HTTP-PATH) (TRANSLATION (EQL :WORLD-DIRECTORY)))
(%%MAP-EXPORT-DIRECTORY
(:URL URL :DATA-TYPES (:WORLD) :DIR-OPTIONS (:FILES)
:DIRECTORIES-P NIL)
(COND ((PATHNAME-DIRECTORY-P TRANSLATED) NIL)
((EXPORT-PATHNAME-P TRANSLATED)
(UNEXPORT-PATHNAME-AS-URL-INFERIOR PATH URL NIL))))
(%UNREGISTER-DIRECTORY-EXPORT-TYPE-MIME-MAJOR-TYPE
:WORLD-DIRECTORY)
(%UNREGISTER-DIRECTORY-EXPORT-TYPE :WORLD-DIRECTORY NIL)
URL)
(PROGN
(DEFMETHOD EXPORT-DIRECTORY-PATHNAME-P
((PATHNAME PATHNAME) (EXPORT-TYPE (EQL :WORLD-DIRECTORY)))
(%MAKE-DATA-TYPE-PATHNAME-PREDICATE PATHNAME (:WORLD) NIL))
(DEFMETHOD DIRECTORY-TYPE-EXPORTS-PATHNAME-EXPORT-TYPE-P
((DIRECTORY-TYPE (EQL :WORLD-DIRECTORY)) (EXPORT-TYPE SYMBOL))
(LET ((MAJOR-TYPE
(MIME-CONTENT-TYPE-MAJOR-TYPE
(PRIMARY-PATHNAME-EXTENSION-FOR-EXPORT-TYPE EXPORT-TYPE))))
(MEMBER MAJOR-TYPE '(:WORLD) :TEST #'EQ))))
(%REGISTER-DIRECTORY-EXPORT-TYPE-MIME-MAJOR-TYPE :WORLD-DIRECTORY '(:WORLD))
(%REGISTER-DIRECTORY-EXPORT-TYPE :WORLD-DIRECTORY 'NIL)
:WORLD-DIRECTORY)
T

You can expand this for some while. Now imagine in one of those
methods you have an error. Which of those macro transformations
did introduce the error (if any)?

I'm not sure how many people on this planet can debug that.
You better read "On Lisp" before trying.

--
http://www.lavielle.com/~joswig/

Rainer Joswig

unread,
Oct 16, 1997, 3:00:00 AM10/16/97
to

In article <30858145...@naggum.no>, Erik Naggum <cle...@naggum.no> wrote:

> * Rainer Joswig
> | Hmm, Common Lisp code with Macros or Macros generating Macros is
> | notoriously difficult to debug. Often you don't have an idea what
> | generated your code or what your current stack frame corresponds to.
> | Without a good idea about Common Lisp and the application it is
> | completely unthinkable to debug some of the advanced programs. There is
> | no real chance for source line debugging.
>
> I would have thought that an (optimize (debug 3)) declaration in effect
> would have made such information available even in a compile-only Common
> Lisp,

Why that? It would still macro expand. You would still need in
most cases to give the Lisp system directives to record necessary debugging
information (who calls, local symbols, symbols in fasls, source
file recording, ...) before compiling. Change a macro or an
inlined function - does your Lisp system give a list of what to recompile?

> but I think I prefer having an interpreter available when debugging,

If the code you want debug is locally understandable. Once
you have 30000+ lines you won't know what to compile and
what not.

> although there is still a problem when running macro expansion functions.
> `step' is source line debugging for me.

Sometimes stepping is not possible. I just ran across a problem
that makes it impossible for me to step such code (reason: only
optimized compiled code is valid, the interpreter complains).

> the only time I have missed source line debugging is when finding the rare
> compiler bug, not when finding my own bugs.

I can live without it. But this is only for experts.
Sometimes I wish library developers would deliver regression
test cases and special debugging options (special error handlers,
ready made trace configurations, logging mechanisms, event replay,
copy stream output to debugging streams, explanations
for the selection of effective methods, useful error conditions,
uninlining, assertions, ...).

--
http://www.lavielle.com/~joswig/

0 new messages