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: Pascal J. Bourguignon
Subject: Re: Is it possible for a macro to expand to nothing?
Date: Mon, 23 Nov 2009 19:42:42 +0100
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/22.3 (darwin)

"Drew Adams" <drew.adams@oracle.com> writes:

>> I think I want to be able to do this:
>> 
>>     (defun foo ()
>>       (setq bar 1)
>>       (ifdef baz (setq bar 2)))
>> 
>> , and if baz is nil at compile time, this function should be 
>> identical to
>> 
>>     (defun foo ()
>>       (setq bar 1))
>
> (defmacro titi (fn)
>   `(defun ,fn ()
>      (setq bar 1)
>      ,@(ifdef baz '((setq bar 2))))))
>
> Assuming that ifdef returns nil if baz is nil, that should give you (defun foo
> () (setq bar 1)). If baz is not nil, it should give you this:
>
> (defun foo ()
>  (setq bar 1)
>  (setq bar 2))
>
> Or something like that.

Yes.  Unfortunately, (ifdef baz '((setq bar 2))) doesn't produce a
valid form when baz is not nil.  When it is used outside of a macro,
that produces an error.  This is not a good property.  It would be
better to keep the contract of macros, that is they take code, and
they produce code, that is, valid forms.  This can be done if you wrap
the body in a progn when baz is not nil.

(defmacro ifdef (expr &rest body)
  (if (eval expr)
     'nil   
     `(progn ,@body)))

(require 'cl) ; as usual

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

(dolist (baz '(nil t))
  (print (macroexpand '(titi foo))))

(defun foo nil (setq bar 1) (progn (setq bar 2)))

(defun foo nil (setq bar 1))
nil

Notice that (defun foo nil (setq bar 1) (progn (setq bar 2))) and 
(defun foo nil (setq bar 1) (setq bar 2)) compile to exactly the same.


-- 
__Pascal Bourguignon__


reply via email to

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