From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: pjb@informatimago.com (Pascal J. Bourguignon) Newsgroups: gmane.emacs.help Subject: Re: Is it possible for a macro to expand to nothing? Date: Mon, 23 Nov 2009 19:33:13 +0100 Organization: Informatimago Message-ID: <87vdh1ccra.fsf@galatea.local> References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1259001647 15343 80.91.229.12 (23 Nov 2009 18:40:47 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 23 Nov 2009 18:40:47 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Mon Nov 23 19:40:40 2009 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1NCdq3-0006eU-K3 for geh-help-gnu-emacs@m.gmane.org; Mon, 23 Nov 2009 19:40:39 +0100 Original-Received: from localhost ([127.0.0.1]:43910 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NCdq3-0004Fb-4j for geh-help-gnu-emacs@m.gmane.org; Mon, 23 Nov 2009 13:40:39 -0500 Original-Path: news.stanford.edu!usenet.stanford.edu!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail Original-Newsgroups: gnu.emacs.help Original-Lines: 104 Original-X-Trace: individual.net 7LMytaWdrMy0CdvI7pn/iwl3IPaIkMn5U1iNiUPa66aUpCm16B Cancel-Lock: sha1:YjUwMTEwMGEzNmQ1ODRjNDg2MjExMjBmZjI1NWNiNThkOTU1YjkzNQ== sha1:OS2sAdnppBKmnQRn9HCzTwBWSs4= Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAQMAAABtzGvEAAAABlBMVEUAAAD///+l2Z/dAAAA oElEQVR4nK3OsRHCMAwF0O8YQufUNIQRGIAja9CxSA55AxZgFO4coMgYrEDDQZWPIlNAjwq9 033pbOBPtbXuB6PKNBn5gZkhGa86Z4x2wE67O+06WxGD/HCOGR0deY3f9Ijwwt7rNGNf6Oac l/GuZTF1wFGKiYYHKSFAkjIo1b6sCYS1sVmFhhhahKQssRjRT90ITWUk6vvK3RsPGs+M1RuR mV+hO/VvFAAAAABJRU5ErkJggg== X-Accept-Language: fr, es, en X-Disabled: X-No-Archive: no User-Agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/22.3 (darwin) Original-Xref: news.stanford.edu gnu.emacs.help:174984 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:70055 Archived-At: Alan Mackenzie writes: > Drew Adams wrote: >>> That is, not to a call to a null defun, but truly to nothing: i.e., >>> the ensuing code (as least, when byte compiled) will be identical to >>> what it would have been, had the macro invocation been omitted. > >>> I want something like this: > >>> (defmacro ifdef (condition &rest forms) >>> "If the compile time CONDITION is non-nil, dump the FORMS to the >>> calling defun. Otherwise do nothing." >>> ......) > >> Hi Alan, > >> I'm not sure what you mean. > > You might not be the only one. ;-) > > 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)) > > . > >> But if you mean something like "insert nothing", then you can do that >> by producing nil and then using ,@ inside a backquote. IOW, instead of >> inserting nil, you splice it in, which means inserting nothing. > > That means I need to have "`,@" in the invoking defun, doesn't it? Maybe > that would work, even if it is ugly. That wouldn't work, backquote is a quote. We cannot produce a macro that returns nothing, because as mentionned, lisp source is not text, but a data structure, and a macro is a function that always return one form to be inserted in that data structure. However, you can return a form that has no side effect: nil or (progn) are good candidates. (I'd tend to favor (progn) as the nil code, since it can be used easily to add forms to it: (append '(progn) '((print 'hi)) '(42)) produces a valid form, while: (append 'nil '((print 'hi)) '(42)) doesn't.) So: (defmacro ifdef (expr &rest body) `(progn ,@(and (eval expr) body))) (setf baz nil) (dolist (baz '(nil t)) (print (macroexpand '(ifdef baz (setq bar 2))))) prints: (progn) (progn (setq bar 2)) Notice that in the case of your example, when baz is nil, the meaning is changed, since it would return the result of the form returned by the ifdef macro, not that of the previous form. You could write: (defun foo () (prog1 (setq bar 1) (ifdef baz (setq bar 2)))) or: (defun foo () (setq bar 1) (ifdef baz (setq bar 2)) bar) depending on what you want. (You could also write a two-branch ifdef instead. Notice that in the case of Common Lisp, there are read-time tests #+ and #-, and read-time evaluation #. that allow you to implement something similar to C #ifdef: '(progn #+baz 1 #-baz 2 #.(+ 1 2)) --> (progn 1 3) or (progn 2 3) Unfortunately the emacs lisp reader is much more primitive... -- __Pascal Bourguignon__