From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Nicolas Richard Newsgroups: gmane.emacs.help Subject: Re: Macro Expansion Inconsistency Date: Wed, 17 Dec 2014 11:04:58 +0100 Message-ID: <87r3vyegmt.fsf@yahoo.fr> References: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1418810888 14798 80.91.229.3 (17 Dec 2014 10:08:08 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 17 Dec 2014 10:08:08 +0000 (UTC) Cc: John Mastro , help-gnu-emacs To: Alexander Shukaev Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Wed Dec 17 11:08:02 2014 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Y1BWQ-0001DN-Kg for geh-help-gnu-emacs@m.gmane.org; Wed, 17 Dec 2014 11:07:58 +0100 Original-Received: from localhost ([::1]:48662 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y1BWP-0006az-Gr for geh-help-gnu-emacs@m.gmane.org; Wed, 17 Dec 2014 05:07:57 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:47333) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y1BW8-0006aX-KU for help-gnu-emacs@gnu.org; Wed, 17 Dec 2014 05:07:46 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Y1BW2-0005hB-MI for help-gnu-emacs@gnu.org; Wed, 17 Dec 2014 05:07:40 -0500 Original-Received: from mxin.ulb.ac.be ([164.15.128.112]:49408) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y1BW2-0005gz-GK for help-gnu-emacs@gnu.org; Wed, 17 Dec 2014 05:07:34 -0500 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AkYGAK5UkVSkD4Xx/2dsb2JhbABag1hYgjawfgEBAQEBAQaGcItECoVyAoEyAQEBAQF9hA0BAQMBAQJ2BQsIAw4TJQ8BBA0HNROIFwEDCQgNv3OOEQFKDYVJAQEBAQYBAQEBHoYAgiqFIIIoB4QpBZFFgx1SgUOBCzCCLoIBMIVMghuDOCKDbT0wAYJCAQEB Original-Received: from mathsrv4.ulb.ac.be (HELO localhost) ([164.15.133.241]) by smtp.ulb.ac.be with ESMTP; 17 Dec 2014 11:05:21 +0100 In-Reply-To: (Alexander Shukaev's message of "Wed, 17 Dec 2014 03:19:14 +0100") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 164.15.128.112 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:101629 Archived-At: Alexander Shukaev writes: > I currently have the following macro baked: > > (defmacro bm-define-flag > (name index character foreground) > (let* ((symbol (intern (format "bm-%s-flag" > (symbol-name name)))) > (character-symbol (intern (format "%s-character" > (symbol-name symbol))))) > (put symbol 'index index) > (put symbol 'character character-symbol) > (eval `(defcustom ,character-symbol > ,character > "Character for flag." > :tag "BM Flag Character" > :group 'buffer-manager > :type 'character)) > (eval `(defface ,symbol > `((t :foreground ,foreground > :weight bold)) > "Face for flag." > :tag "BM Flag Face" > :group 'buffer-manager-faces)))) > [...] > causes the error: (void-variable bm-xxx-flag) in `eval' > [...] > How to overcome it? Quick'n'very-dirty : add nil or t (or anything that can be evaluated twice safely) at the end of your macro definition. > Do you have any further recommendations on this macro? It's awful :) But don't worry : it's easy to write awful things, and it's good that you post about it here. In your case I'd point out these problems : (i) it uses explicit eval for no good reason (ii) it doesn't return code (that's the error you see) (iii) it relies on dynamical binding (because of ',foreground' in a second layer of quasi-quoting, which is only evalled by the explicit eval.). I think this works (lightly tested) : (defmacro bm-define-flag (name index character foreground) (let* ((symbol (intern (format "bm-%s-flag" (symbol-name name)))) (character-symbol (intern (format "%s-character" (symbol-name symbol))))) (put symbol 'index index) (put symbol 'character character-symbol) `(progn ;; this is the code we're going to return after expansion. ;; Emacs will eval the whole progn form. (defcustom ,character-symbol ,character "Character for flag." :tag "BM Flag Character" :group 'buffer-manager :type 'character) (defface ,symbol '((t :foreground ,foreground ;; the comma can be used, ;; even after normal quoting :weight bold)) "Face for flag." :tag "BM Flag Face" :group 'buffer-manager-faces)))) If you'd like to read more about macros, I wrote about them at http://lists.gnu.org/archive/html/help-gnu-emacs/2014-09/msg00473.html (there's a typo in the first paragraph, apply `sed s/evaluation time/expansion time/' please) HTH, -- Nicolas Richard