From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: Macro expansion: Why doesn't the invoked macro see (let (variables))from the invoking one? Date: Wed, 08 Feb 2012 14:52:45 -0500 Message-ID: References: <20120208172638.GB3523@acm.acm> <50AF0C80D632450597698E2B44C378AA@us.oracle.com> <20120208192800.GA31761@acm.acm> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: dough.gmane.org 1328730782 11610 80.91.229.3 (8 Feb 2012 19:53:02 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Wed, 8 Feb 2012 19:53:02 +0000 (UTC) Cc: Drew Adams , emacs-devel@gnu.org To: Alan Mackenzie Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Feb 08 20:53:01 2012 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1RvDZa-0001I4-VR for ged-emacs-devel@m.gmane.org; Wed, 08 Feb 2012 20:52:59 +0100 Original-Received: from localhost ([::1]:43739 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RvDZa-0007sc-IM for ged-emacs-devel@m.gmane.org; Wed, 08 Feb 2012 14:52:58 -0500 Original-Received: from eggs.gnu.org ([140.186.70.92]:34629) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RvDZU-0007sV-SG for emacs-devel@gnu.org; Wed, 08 Feb 2012 14:52:57 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RvDZP-0001GL-7t for emacs-devel@gnu.org; Wed, 08 Feb 2012 14:52:52 -0500 Original-Received: from ironport2-out.teksavvy.com ([206.248.154.183]:46562) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RvDZP-0001GE-5P for emacs-devel@gnu.org; Wed, 08 Feb 2012 14:52:47 -0500 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EAI7RMk9MCqD0/2dsb2JhbABDrwmBCIFzAQVWIxALDiYSFBgNJMFSi3USAgIDBgIEAgEEAgIMBg2EHgEEBB6DOgSIRpsIhFo X-IronPort-AV: E=Sophos;i="4.73,385,1325480400"; d="scan'208";a="162159803" Original-Received: from 76-10-160-244.dsl.teksavvy.com (HELO pastel.home) ([76.10.160.244]) by ironport2-out.teksavvy.com with ESMTP/TLS/ADH-AES256-SHA; 08 Feb 2012 14:52:45 -0500 Original-Received: by pastel.home (Postfix, from userid 20848) id 372EB59047; Wed, 8 Feb 2012 14:52:45 -0500 (EST) In-Reply-To: <20120208192800.GA31761@acm.acm> (Alan Mackenzie's message of "Wed, 8 Feb 2012 19:28:00 +0000") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 206.248.154.183 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:148373 Archived-At: > (defmacro run-hooks-here () > (setq hooks-called t) <================= flag variable > `(run-hooks ',hook (if ,mode ',hook-on ',hook-off))) > (defmacro define-minor-mode (....) > .... > (let (... hooks-run) > .... > ,@body <================= expand invoker's forms This comment is wrong: ",@body" just plugs in the `body' without macro-expanding it. > <====== There may be (run-hooks-here) here. > ,@(unless hooks-run `((run-hooks-here))) <========= test flag You can do that, but you then need to make sure the `body' gets macro-expanded while the `let' is live, i.e. during the expansion of the call to `define-minor-mode'. You can do it with something like (defmacro define-minor-mode (....) .... (let (... hooks-run) .... ,@(macroexpand-all body) <================= expand invoker's forms <====== There may be (run-hooks-here) here. ,@(unless hooks-run `((run-hooks-here))) <========= test flag But note that this counts as ugly. We use such tricks in cl-macs.el to figure out whether `body' uses `return-from' within a `block' (in order to optimize away the `catch' that's otherwise needed), but it's ugly, inefficient, and brittle. An :after-hook (or :late-code or some other name you prefer) is much better in this regard. Stefan