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

Context of macro call

4 views
Skip to first unread message

Software Scavenger

unread,
Jan 2, 2002, 1:04:45 AM1/2/02
to
I know I can get an environment object in a macro, to get bindings.
But can I get the outer level forms, which contain the form that
invoked the macro? Not that I would want to mess with them, of
course, but just to get information from them for error messages, to
tell the programmer where the macro was invoked with the wrong
arguments etc.

Rahul Jain

unread,
Jan 2, 2002, 2:49:14 AM1/2/02
to
cubic...@mailandnews.com (Software Scavenger) writes:

I think the best course of action in these cases is to use ERROR and
let the lisp environment do what it normally does, so that the
behavior is consistent with what the user expects

--
-> -/- - Rahul Jain - -\- <-
-> -\- http://linux.rice.edu/~rahul -=- mailto:rj...@techie.com -/- <-
-> -/- "I never could get the hang of Thursdays." - HHGTTG by DNA -\- <-
|--|--------|--------------|----|-------------|------|---------|-----|-|
Version 11.423.999.221020101.23.50110101.042
(c)1996-2002, All rights reserved. Disclaimer available upon request.

Rahul Jain

unread,
Jan 2, 2002, 2:47:19 AM1/2/02
to
cubic...@mailandnews.com (Software Scavenger) writes:

I think the best course of action in these cases is to use ERROR and

Software Scavenger

unread,
Jan 2, 2002, 5:50:16 AM1/2/02
to
Rahul Jain <rj...@sid-1129.sid.rice.edu> wrote in message news:<87wuz1j...@photino.sid.rice.edu>...

> I think the best course of action in these cases is to use ERROR and
> let the lisp environment do what it normally does, so that the
> behavior is consistent with what the user expects

ERROR is how we give the user an error message. But that error
message has to say something. In the case of incorrect macro
arguments, it should say what those macro arguments were, why they
were wrong, and where they are in the program. The question is how
the macro knows where it was called, so it can make that information
part of the error message.

Christophe Rhodes

unread,
Jan 2, 2002, 6:10:21 AM1/2/02
to
cubic...@mailandnews.com (Software Scavenger) writes:

Have you tried Rahul's suggestion? Most lisp environments will report
the position of an error, enclosing source, and so on when they
receive an error.

Christophe
--
Jesus College, Cambridge, CB5 8BL +44 1223 510 299
http://www-jcsu.jesus.cam.ac.uk/~csr21/ (defun pling-dollar
(str schar arg) (first (last +))) (make-dispatch-macro-character #\! t)
(set-dispatch-macro-character #\! #\$ #'pling-dollar)

Erik Naggum

unread,
Jan 2, 2002, 6:39:30 AM1/2/02
to
* cubic...@mailandnews.com (Software Scavenger)

| ERROR is how we give the user an error message. But that error message
| has to say something. In the case of incorrect macro arguments, it
| should say what those macro arguments were, why they were wrong, and
| where they are in the program. The question is how the macro knows where
| it was called, so it can make that information part of the error message.

Would not the compiler know this and make it part of its error message?

///
--

Barry Margolin

unread,
Jan 2, 2002, 1:25:18 PM1/2/02
to

There's no requirements on the content of error messages, so a portable
program cannot depend on them containing this information.

Unfortunately, there are no portable operations to query the environment
for this information, either.

--
Barry Margolin, bar...@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Software Scavenger

unread,
Jan 2, 2002, 2:02:01 PM1/2/02
to
Erik Naggum <er...@naggum.net> wrote in message news:<32189603...@naggum.net>...

> Would not the compiler know this and make it part of its error message?

Here is an example in the LWW 4.1.20 listener:

CL-USER 64 >


(defmacro testmacro (&rest list)
(ccase (car list)
(a 100)
(b 101)
(c 102)))

TESTMACRO

CL-USER 65 > (defun testfun1 () (testmacro b))
TESTFUN1

CL-USER 66 > (testfun1)
101

CL-USER 67 > (defun testfun2 () (testmacro x))

Error: X fell through CCASE expression.
Wanted one of (A B C).
1 (continue) Return NIL.
2 Supply a new value for (CAR LIST).
3 (abort) Return to level 0.
4 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed, or :? for other
options

CL-USER 68 : 1 >

What I want is for example to use case instead of ccase and have the
otherwise clause of the case give an error telling where the macro was
called and what arguments it was called with and why they were wrong.

Kent M Pitman

unread,
Jan 2, 2002, 2:38:47 PM1/2/02
to
Barry Margolin <bar...@genuity.net> writes:

> In article <32189603...@naggum.net>, Erik Naggum <er...@naggum.net> wrote:
> >* cubic...@mailandnews.com (Software Scavenger)
> >| ERROR is how we give the user an error message. But that error message
> >| has to say something. In the case of incorrect macro arguments, it
> >| should say what those macro arguments were, why they were wrong, and
> >| where they are in the program. The question is how the macro knows where
> >| it was called, so it can make that information part of the error message.
> >
> > Would not the compiler know this and make it part of its error message?
>
> There's no requirements on the content of error messages, so a portable
> program cannot depend on them containing this information.
>
> Unfortunately, there are no portable operations to query the environment
> for this information, either.

On the other hand, it's possible without an established protocol on this,
that if you COULD add context, you'd have to know whether the system did
also, to avoid getting the information added to the message more than once.

I kind of prefer to assume that the handler or reporter of warnings will
deal with context tissues (at least the filepos of the toplevel expression
containing the offending code), and that the signallers do not have that
responsibility. There are many fewer handlers/reporters than there are
signalers in most cases, so the code gets less cluttered if you assume the
right place for context is there.

Thomas F. Burdick

unread,
Jan 2, 2002, 2:44:31 PM1/2/02
to
cubic...@mailandnews.com (Software Scavenger) writes:

This is a shortcoming of your implementation. I'd bug the vendor
about it. Is there a debugging command to get this info? You could
also look through the environment object, and see if there's the
source form in there. Your same example in CMUCL gives me:

* (testfun2)
In: LAMBDA NIL
(TESTMACRO X)
Error: (during macroexpansion)
X fell through CCASE expression. Wanted one of (C B A).


Error in function TESTFUN2: Execution of a form compiled with errors:
(TESTMACRO X)

Restarts:
0: [ABORT] Return to Top-Level.

Debug (type H for help)

(TESTFUN2)
Source: (BLOCK TESTFUN2 (TESTMACRO X))
0]

I'm actually kind of surprised that LispWorks doesn't give you the
source form.

--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'

Jochen Schmidt

unread,
Jan 2, 2002, 9:12:32 PM1/2/02
to
Thomas F. Burdick wrote:

I tried it in LispWorks 4.2

If you place the definition in a new buffer in the LW Editor and execute
the "Compile Buffer" command an debugger window pops up with the error
message like above. If you then click on the "Abort" button the following
message is printed

Compilation aborted due to error in TESTFUN2:


X fell through CCASE expression.
Wanted one of (A B C).

Which is quite ok for me. The information that it was the call to TESTMACRO
that failed in TESTFUN2 is actually given in the backtrace of the debugger.

I think one actually knows well enough what got evaluated if you do it
in the listener - what counts is the stuff in the buffers and files were
locating the erroneous element is not _that_ easy.

ciao,
Jochen

--
http://www.dataheaven.de

Thomas F. Burdick

unread,
Jan 2, 2002, 9:11:31 PM1/2/02
to
Jochen Schmidt <j...@dataheaven.de> writes:

> I tried it in LispWorks 4.2
>
> If you place the definition in a new buffer in the LW Editor and execute
> the "Compile Buffer" command an debugger window pops up with the error
> message like above. If you then click on the "Abort" button the following
> message is printed
>
> Compilation aborted due to error in TESTFUN2:
> X fell through CCASE expression.
> Wanted one of (A B C).
>
> Which is quite ok for me. The information that it was the call to TESTMACRO
> that failed in TESTFUN2 is actually given in the backtrace of the debugger.
>
> I think one actually knows well enough what got evaluated if you do it
> in the listener

Usually, but not always. Sometimes you might have a function with
several calls to a macro in it. But then I'd expect the backtrace
command in the debugger to show you which call caused the error.

> - what counts is the stuff in the buffers and files were
> locating the erroneous element is not _that_ easy.

I agree with this, but if the OP feels strongly enough about this to
make a mess of his macro so he can show its context in places where
LWW doesn't, I still think it's good advice for him to complain to the
vendor. Otherwise, he might write his own macroexpand so he can keep
that information around for errors :-). But seriously, this is
something that the user can't do reasonably, so it's in the vendor's
domain, and he sees them as failing him here.

Software Scavenger

unread,
Jan 3, 2002, 7:09:36 AM1/3/02
to
t...@conquest.OCF.Berkeley.EDU (Thomas F. Burdick) wrote in message news:<xcvr8p8...@conquest.OCF.Berkeley.EDU>...

> I agree with this, but if the OP feels strongly enough about this to
> make a mess of his macro so he can show its context in places where

How would it make a mess of my macro? Lisp macros never have to be
messy, regardless of how sophisticated they get. And why would anyone
think I have strong feelings about anything just because I want to
provide a reasonable level of error message quality?

Right now it looks like the best way for me to learn how to find the
kind of information I want might be to spend some time exploring the
internals of the LEXICAL package and/or other such packages.
Somewhere I should be able to at least find the name of the defun
being executed. I hope I don't have to look at stack frames and get
it from the local variables of the defun evaluator.

Jochen Schmidt

unread,
Jan 3, 2002, 8:49:59 AM1/3/02
to
Software Scavenger wrote:

As I already said you get the information in which function the error
occured when compiling your code in a buffer or a file.
If it happens in the listener you can go the stack-frames up and inspect
the bindings in that frames for the function name. I'm not sure if that
works in more complicated situations but the information is at least there.

It would be nice if there where some kind of documentation of the stuff in
the LEXICAL package. I would be very interested in getting hold of the
declarations corresponding to actual bindings so that one could write macros
that can optimize code based on that information.

Thomas F. Burdick

unread,
Jan 3, 2002, 1:43:20 PM1/3/02
to
cubic...@mailandnews.com (Software Scavenger) writes:

I would say that your wanting to write complicated error message
generating code, and your willingness to look through the internals of
your implementation, it's safe to say that you don't feel that your
implementation is doing a good enough job of giving you context
information on where the error occured; and strongly enough to go to a
fair amount of effort.

Perhaps we have different priorities, but I think it's the
implementation's job to do this. If I were unhappy with the way CMUCL
did this, I'd figure out how to do what I want and submit a patch. If
I used a commercial implementation, I'd want them to have done this
already. When I'm writing macros, I only want to write the minimum in
error generating code, because it obscures the real purpose of the
macro, which is to do it's job, not primarily to report errors.

0 new messages