[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: do-nothing macro generates nil nevertheless
- To: info-mcl@digitool.com
- Subject: Re: do-nothing macro generates nil nevertheless
- From: yost@rclsgi.eng.ohio-state.edu (Dave Yost)
- Date: 27 Feb 1995 03:07:53 GMT
- Organization: Dave Yost's house
- References: <3iqno7$mab@news.internex.net>, <gat-260295131710@milo.jpl.nasa.gov>
- Sender: owner-info-mcl@digitool.com
In article <gat-260295131710@milo.jpl.nasa.gov>,
Erann Gat <gat@robotics.jpl.nasa.gov> wrote:
>In article <3iqno7$mab@news.internex.net>, yost@rclsgi.eng.ohio-state.edu
>(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.:
>
>(progn
> 3
> #+debug(do-debugging-stuff))
My macros are more sophisticated than this.
I hope to post them soon.
>> Consider this macro:
>>
>> (defmacro mac1 () nil)
>>
>> Now consider this form:
>>
>> (progn
>> 3
>> (mac1))
>>
>> 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
>to itself.
>
>> 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.