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: Drew Adams
Subject: RE: Is it possible for a macro to expand to nothing?
Date: Mon, 23 Nov 2009 14:09:11 -0800

> > Sorry, but it works just fine. I do this all the time.
> 
> No, it doesn't:
> (defmacro ifdef (expr &rest body)
>    (and (eval expr) `(progn ,@body)))
> (ifdef t ((setq bar 2)))
> Debugger entered--Lisp error: (invalid-function (setq bar 2))

You seem to be complaining about yourself. I never suggested using such a macro.

All I suggested was to use backquote with ,@ to splice in a list with the
element that Alan conditionally wants in the macroexpansion. That's the way to
add something or nothing to a list: put the something or nothing in a list, then
splice in that list.

The list to be built here is a defun expression. It is then evaluated without
problem.

> I said that it was a bad idea to take the habit of giving
> an invalid form to a macro to get an invalid form from it.

Sorry, dunno what you're saying. There wasn't anything invalid in what I
suggested.

As far as I'm concerned, all that's really involved is writing a macro that
expands to a list that contains or doesn't contain the element in question. Any
such list is a valid _list_.

When the list resulting from macroexpansion is then EVALUATED, yes, of course
its car must be a defined function, macro, `lambda', etc. (or the list must be
nil). That is an entirely different matter. That is a consideration for _any_
macro one writes.

In Alan's case, the resulting list has `defun' as its car. It is a valid defun
expression whose evaluation defines a function.

The only thing relevant here, AFAICT, is how to create the list Alan wants: a
list that conditionally contains some element. Backquote plus ,@ is the answer.

> Notice also my alternative solution uses macroexpand.   This is a clue
> that if you want to go that way, you should use a function rather than
> a macro:
>    (defun %parenthesized-ifdef (expr forms)
>       (if expr
>           '()
>           `((progn ,@forms))))
>    (defmacro titi (fn)
>       `(defun ,fn  ()
>           (setq bar 1)
>           ,@(%parenthesized-ifdef baz '((setq bar 2)))))
> 
> (macroexpand '(titi foo))
> --> (defun foo nil (setq bar 1) (progn (setq bar 2)))

Dunno why you do all that. Just `,@forms is as useful here as `((progn ,@forms))
- a defun body is an implicit progn. (And there is no need to quote nil.)

Again, all of that code boils down to just this (which is what I wrote earlier):

(defmacro titi (fn)
  `(defun ,fn ()
    (setq bar 1)
    ,@(and baz '((setq bar 2)))))

I'm sure you know what you're talking about, and I know what I'm talking about
;-). The only real question is whether either of us has actually helped Alan at
all.





reply via email to

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