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: Sat, 28 Nov 2009 01:06:10 +0100
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/22.3 (darwin)

Tim X <timx@nospam.dev.null> writes:

> On the other hand, Alan's arguments also have merit. If a macro can be
> useful in generating something other than a form that can be evaluated,
> such as a data structure and can do so in a way that is cleaner/simpler
> or just easier to understand than doing the same using functions, then
> it would make sense. His examples from the C modes seem to be a case in
> point. 


Perhaps Alan's problem with functions comes from the confusion between
backquote and macros.  Since backquote (and , and ,@) are often used
in macros, some people believe they can be used only in macros, and
that they ARE what macros are.


Far from it!  I don't know any language more orthogonal than lisp.


Backquote can be used in a function to build a s-exp (including part
of a form) as it can be used anywhere.

Therefore it is really not easier to use macros to generate parts of a
form than function.



You should never write or use a macro to generate data.  To generate
data, always use functions:

(defun generate-cond-clause (var predicate body)
   `((,predicate ,var) ,@body))


So then you can write a macro using this functio:

(defmacro pcase (expr &rest clauses)
  (let ((var (gensym)))
    `(let ((,var ,expr))
        (cond
          ,@(mapcar (lambda (clause)
                       (generate-cond-clause var (first clause) (rest clause)))
                    clauses)))))

(macroexpand '
 (pcase 42
   (oddp     (print 'odd)      1)
   (zerop    (print 'zero)     0)
   (integerp (print 'even)     2)
   (identity (print 'anything) 3)
   (null     (print 'null)     nil)))
-->
(let ((G62061 42))
   (cond ((oddp G62061) (print (quote odd)) 1)
         ((zerop G62061) (print (quote zero)) 0)
         ((integerp G62061) (print (quote even)) 2)
         ((identity G62061) (print (quote anything)) 3)
         ((null G62061) (print (quote null)) nil)))



If you wanted to use macros, in addition to the complexity of having
to use macroexpand to use it, you would have the difficulty of passing
the parameters, since a macro gets it's parameters from the source
form.  In the case of a function, you have the choice to quote or not
to quote the parameters, with macros they're always quoted for you.


-- 
__Pascal Bourguignon__


reply via email to

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