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: Lexical binding Date: Mon, 04 Apr 2011 12:22:14 -0400 Message-ID: References: <4D98629F.9070506@gnu.org> <4D99038B.7060702@gnu.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: dough.gmane.org 1301934172 31708 80.91.229.12 (4 Apr 2011 16:22:52 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Mon, 4 Apr 2011 16:22:52 +0000 (UTC) Cc: Juanma Barranquero , emacs-devel@gnu.org To: Christian Ohler Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Apr 04 18:22:47 2011 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6mY2-00082w-6P for ged-emacs-devel@m.gmane.org; Mon, 04 Apr 2011 18:22:38 +0200 Original-Received: from localhost ([127.0.0.1]:52612 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q6mY1-00075g-0z for ged-emacs-devel@m.gmane.org; Mon, 04 Apr 2011 12:22:37 -0400 Original-Received: from [140.186.70.92] (port=44279 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q6mXl-00073P-LG for emacs-devel@gnu.org; Mon, 04 Apr 2011 12:22:26 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q6mXg-0007Cz-My for emacs-devel@gnu.org; Mon, 04 Apr 2011 12:22:21 -0400 Original-Received: from ironport2-out.teksavvy.com ([206.248.154.181]:12109 helo=ironport2-out.pppoe.ca) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q6mXg-0007CQ-K8; Mon, 04 Apr 2011 12:22:16 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvsEAA7vmU1Ld/Y6/2dsb2JhbAClYXi/d4VrBJY/ X-IronPort-AV: E=Sophos;i="4.63,298,1299474000"; d="scan'208";a="103091722" Original-Received: from 75-119-246-58.dsl.teksavvy.com (HELO ceviche.home) ([75.119.246.58]) by ironport2-out.pppoe.ca with ESMTP/TLS/ADH-AES256-SHA; 04 Apr 2011 12:22:15 -0400 Original-Received: by ceviche.home (Postfix, from userid 20848) id 027AC660C2; Mon, 4 Apr 2011 12:22:14 -0400 (EDT) In-Reply-To: <4D99038B.7060702@gnu.org> (Christian Ohler's message of "Mon, 04 Apr 2011 09:32:27 +1000") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 206.248.154.181 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:138129 Archived-At: >>> (loop for (nil width . nil) in bs-attributes-list >>> if (numberp width) sum width) >> Yes, but it is less informative. BTW, I believe part of the problem is that the loop macro will use something of the form (let (var) (while ... (setq var ...) ...)) instead of (while ... (let ((var ...)) ...)) The former is likely to bump into the current problem, while the second isn't. The former is popular in Elisp because it's slightly faster, but with lexical scoping the second is actually more efficient. This is in part because a lexical `let' is cheaper so it can be moved into the loop without problems, and in other part because the second form avoids some more costly cases: let's take `dotimes' as an example. What should (let ((res ())) (dotimes (i 3) (push (lambda () i) res)) res) return? Clearly it will be a list of 3 functions, each one taking 0 args and returning a number, but what should the exact return value be? With the let-while-setq form of the loop, you'd get three times the same function returning 3, whereas with the while-let form you'd get functions returning 2, 1, and 0. To get the first result, you need to make sure all three functions refer to some memory cell holding the value of the variable `i', so you get an extra indirection. I also find the second behavior more desirable. So I've changed the dotimes (and dolist) macros to use the while-let instead of let-while-setq form when used with lexical scoping. Maybe we should do the same for loop, but I'm definitely not going to take on this challenge. Stefan