From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.help Subject: Re: Unreferenced symbols in closures, and a problem with closures in minor modes Date: Tue, 28 May 2013 21:28:44 -0400 Message-ID: References: <1369780558.54419.YahooMailClassic@web141103.mail.bf1.yahoo.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1369790968 9895 80.91.229.3 (29 May 2013 01:29:28 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 29 May 2013 01:29:28 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Wed May 29 03:29:27 2013 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 1UhVCh-0000tZ-6f for geh-help-gnu-emacs@m.gmane.org; Wed, 29 May 2013 03:29:27 +0200 Original-Received: from localhost ([::1]:56996 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UhVCg-0006Wp-PI for geh-help-gnu-emacs@m.gmane.org; Tue, 28 May 2013 21:29:26 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:40275) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UhVCU-0006Wj-VM for help-gnu-emacs@gnu.org; Tue, 28 May 2013 21:29:16 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UhVCU-000712-1M for help-gnu-emacs@gnu.org; Tue, 28 May 2013 21:29:14 -0400 Original-Received: from plane.gmane.org ([80.91.229.3]:58870) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UhVCT-00070n-RF for help-gnu-emacs@gnu.org; Tue, 28 May 2013 21:29:13 -0400 Original-Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1UhVCO-0000bp-2b for help-gnu-emacs@gnu.org; Wed, 29 May 2013 03:29:08 +0200 Original-Received: from 76-10-147-173.dsl.teksavvy.com ([76.10.147.173]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Wed, 29 May 2013 03:29:08 +0200 Original-Received: from monnier by 76-10-147-173.dsl.teksavvy.com with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Wed, 29 May 2013 03:29:08 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 49 Original-X-Complaints-To: usenet@ger.gmane.org X-Gmane-NNTP-Posting-Host: 76-10-147-173.dsl.teksavvy.com User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux) Cancel-Lock: sha1:QT2wjH6wXrT1kW5LIP3d1R9JDLo= X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 80.91.229.3 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:91114 Archived-At: > (setq lexical-binding t) > As expected, (let ((x 0)) (lambda () x)) -> (closure ((x . 0) t) nil x) > But, (let ((x 0)) (lambda () 0)) -> (closure ((x . 0) t) nil 0) > And, (lambda (x) x) -> (closure (t) (x) x) > Why do closures' lexical environments include unreferenced symbols? Because you're testing interpreted code: the interpreter does not take the time to traverse the whole lambda body to figure out which variables are free and which aren't. That could have a significant performance impact. Rest assured that when you byte-compile this code, only the free variables will be captured, tho. > And why produce a closure with an empty environment, instead of just > a lambda form? Because the two are not equivalent in general: when running the body of (closure (t) (x) ), `x' is lexically bound, whereas when running the body of (lambda (x) ), `x' is dynamically bound. > And I have a problem with unwanted closures in minor modes: [...] > Argh! Surely this is a misfeature? Yup. > I have no idea what the symbol i means or where it came from. If it > were setting i to nil in the lexical environment, it would be (i), > not i. Indeed. A sole `var' in this environment is used to keep track of the fact that a (defvar var) was encountered and hence `var' should be treated as dynamically scoped when we run a `let'. Again, this only applies to interpreted code. > Also, the two closures are identical, yet add-hook isn't supposed to > add duplicates. No idea why that is, indeed. To add&remove functions from hooks, it's much better to make sure you actually pass the exact same object (not just one that should hopefully be `equal'). Equality of functions is tricky business (both in theory and in practice). Stefan