help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Is it possible for a macro to expand to nothing?


From: Alan Mackenzie
Subject: Re: Is it possible for a macro to expand to nothing?
Date: Tue, 24 Nov 2009 16:39:20 +0000 (UTC)
User-agent: tin/1.6.2-20030910 ("Pabbay") (UNIX) (FreeBSD/4.11-RELEASE (i386))

Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> Alan Mackenzie <acm@muc.de> writes:

>> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>>> Alan Mackenzie <acm@muc.de> writes:

>>>> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>>>>> "Drew Adams" <drew.adams@oracle.com> writes:

> Valid lisp code is the kind of lisp code that eval can process and
> return the result without signaling an error (it can signal errors
> internally, if they are caught).

OK.  It is quite valid for macros to generate portions of valid code, or
data upon which code can operate.

> My claim is that it is not a good style to write a macro that produces
> non valid lisp code, .....

So you have said, time after time, without producing any coherent
reasoning to back it up.  The following ....

> .... because lisp macros are designed to produce code that will be
> evaluated by the lisp eval,

, is a mere assertion which I am convinced is false.  It seems to be on a
par with saying "gotos are harmful".  Well, yes they are, sort of, but on
other occasions are useful indeed.  The same surely applies to lisp
macros which generate things not evalable.

> If you want to transform code for other processors, or random data, use
> functions.

Functions are not as usable as macros, or are more awkward and hence
error prone, or require excessive use of `eval-while-compile' and lots of
juggling with , ,@ ` and the like.

Your notion of the correct use of macros seems to be a religious idea
rather than one fully thought through.  You justify it with circular
reasoning.  Whilst using a macro to generate an evalable form may be the
most usual thing, there is no reason not to use it to produce other list
structure.



>>> But cc-langs.el only defines four macros and they all generate
>>> perfectly good lisp code.

>> Any macro, once debugged, generates "perfectly good" lisp code.  I
>> don't understand where this notion of "perfectly good" comes from.

> It means valid lisp code, see definition above.

Circular reasoning.

>>> Unfortunately, most of emacs lisp code is bad code.  Functions one
>>> kilometer long, chained with one or more others one kilometer long.
>>> Copy-and-pasted chunks instead of abstracting it away.  Etc.

>> I can't disagree with that, sadly.  However I think Emacs's code base
>> is better than a typical 25 yo application still under development (if
>> there is such a beast).

> Yes, the fact that it still runs, is still useful, and can still be
> maintained despite these bad parts is proof of it, that it's better
> than typical 25 yo or even a lot of much younger programs.


>>> The general contract of a macro is that it returns valid forms.

>> Sorry, Pascal, you're just restating the same thing again, not
>> answering my question.  Why should I accept this "general contract of
>> a macro"?  I haven't signed it.  ;-) Is there some respected Lisp guru
>> who says this?

> It comes directly from the definition of defmacro,

>    defmacro is a special form in `src/eval.c'.
>    (defmacro name arglist [docstring] [decl] body...)

>    Define name as a macro.
>    The actual definition looks like
>     (macro lambda arglist [docstring] [decl] body...).
>    When the macro is called, as in (name ARGS...),
>    the function (lambda arglist body...) is applied to
>    the list ARGS... as it appears in the expression,
>    and the result should be a form to be evaluated instead of the original.

Oh, come on!  That last sentence is a tutorial, motivating one, expressed
in the slightly loose, colloquial language of the hacker.  "a form to be
evaluated" is here shorthand for something like "some sort of atom or
list structure which fits into the slot where the invocation is housed"

>> What would this guru say about the macro which generates a
>> font-lock-defaults structure?

> If this structure cannot be passed to eval without signaling an error,
> then I would say that it is bad style to use a macro to generate such
> data.

OK.  So people who might have benefitted from a clever macro now have to
do things more laboriously and more erroneously.  Another example you
would call bad would be `define-minor-mode' which, in addition to
creating a top level command also creates a keymap, a syntax table, and
so on.  Would you propose eliminating `define-minor-mode' from Emacs?


>>> (defmacro ifdef (expr &rest body)
>>>   (and (eval expr) `(progn ,@body)))

>> That version of ifdef is ugly because it contains an obtrusive
>> `progn'.

> In a way here, progn is the dual of list.

> When you want to generate a list of data, you use list:

>  `(list  ,expr1 ,expr2 ... ,exprN)

> When you want to generate a list of code, you use progn:

>  `(progn ,form1 ,form2 ... ,formN)


> It is not obtrusive in any way, it only shows that we are generating
> code, not mere data.

It makes the generated code more difficult to read, because it has no
function, unless it has some specific function.


>> It seems this `progn' is there purely to satisfy
>> the (as yet unsubstantiated) injunction to return only "perfectly good"
>> lisp forms.

> Not 'purely'.  You could optimize it out when unnecessary with:

>  (defun progn-encapsulate (forms)
>    (if (= 1 (length forms)) 
>       (first forms)
>       (list* 'progn forms)))

, or I could just have the macro return (form1 form2 .... formn), ready
to be spliced into the caller.

-- 
Alan Mackenzie (Nuremberg, Germany).



reply via email to

[Prev in Thread] Current Thread [Next in Thread]