[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: do-nothing macro generates nil nevertheless
- To: firstname.lastname@example.org
- Subject: Re: do-nothing macro generates nil nevertheless
- From: email@example.com (Dave Yost)
- Date: 27 Feb 1995 03:07:53 GMT
- Organization: Dave Yost's house
- References: <firstname.lastname@example.org>, <email@example.com>
- Sender: firstname.lastname@example.org
In article <email@example.com>,
Erann Gat <firstname.lastname@example.org> wrote:
>In article <email@example.com>, firstname.lastname@example.org
>(Dave Yost) wrote:
>>I've been implementing some debug macros that only
>generate code depending on what's in *features*.
>The proper way to do this is to use the #+ read macro, e.g.:
My macros are more sophisticated than this.
I hope to post them soon.
>> Consider this macro:
>> (defmacro mac1 () nil)
>> Now consider this form:
>> which returns nil. (in MCL and CMU-CL)
>> This seems to me to be a misfeature.
>No, this is doing the Right Thing. The body of mac1 returns nil which
>means that (progn 3 (mac1)) becomes (progn 3 nil) which should return nil.
>> A macro's job is to return a list to be compiled.
>> If it returns nil, I would have thought that would mean
>> that nothing should be compiled. That would be useful.
>Not quite. A macro returns a FORM to be compiled, not a list. Nil
>is a perfectly valid Common Lisp form, one that happens to evaluate
>> If you need a macro to compile in the constant nil, you
>> can have it return 'nil.
>In Common Lisp, nil, 'nil, () and '() are all the same thing.
You're telling me how it works, and I'm saying how I think it should work.
My point is that some functionality is not provided:
namely, the ability of a macro to expand into _nothing_.
>Another way to achieve the effect you want is to write a surrounding
>macro that removes all the nil forms, e.g.:
>(defmacro yost-progn (&body body)
> `(progn ,@(remove nil (mapcar #'macroexpand body))
>but this is pretty hideous programming practice. Your "implicit-progn"
>could be implemented analogously, by making a pass over the body and
>replacing every occurence of (form) (return-value-trasnparent ...) with
>(prog1 (form) ...).
This is a hack that doesn't address the missing functionality.
>> (with-captured-return-values (var) &body body)
>Isn't this the same as LET?
No. The var argument is bound to a list of the value(s) that
would be returned if this form were not present, and if no other
forms follow in the progn.