From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Drew Adams Newsgroups: gmane.emacs.help Subject: RE: DynamicBindingVsLexicalBinding Date: Sat, 12 Oct 2013 13:53:43 -0700 (PDT) Message-ID: <3da7567e-5a00-400a-bf72-5430740e2782@default> References: <52598D4A.2010901@easy-emacs.de> <871u3qjq0j.fsf@yandex.ru> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1381611260 28120 80.91.229.3 (12 Oct 2013 20:54:20 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 12 Oct 2013 20:54:20 +0000 (UTC) Cc: "help-gnu-emacs@gnu.org List" To: Dmitry Gutov , =?utf-8?B?QW5kcmVhcyBSw7ZobGVy?= Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Sat Oct 12 22:54:22 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 1VV6CX-0001Cx-BI for geh-help-gnu-emacs@m.gmane.org; Sat, 12 Oct 2013 22:54:17 +0200 Original-Received: from localhost ([::1]:59323 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VV6CW-0005gp-Vg for geh-help-gnu-emacs@m.gmane.org; Sat, 12 Oct 2013 16:54:16 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:33871) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VV6CF-0005eh-CH for help-gnu-emacs@gnu.org; Sat, 12 Oct 2013 16:54:07 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VV6C6-0008MS-O1 for help-gnu-emacs@gnu.org; Sat, 12 Oct 2013 16:53:59 -0400 Original-Received: from userp1040.oracle.com ([156.151.31.81]:49362) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VV6C6-0008MN-GK for help-gnu-emacs@gnu.org; Sat, 12 Oct 2013 16:53:50 -0400 Original-Received: from ucsinet21.oracle.com (ucsinet21.oracle.com [156.151.31.93]) by userp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id r9CKrijk001147 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sat, 12 Oct 2013 20:53:45 GMT Original-Received: from aserz7021.oracle.com (aserz7021.oracle.com [141.146.126.230]) by ucsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r9CKrh76012930 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 12 Oct 2013 20:53:44 GMT Original-Received: from abhmt107.oracle.com (abhmt107.oracle.com [141.146.116.59]) by aserz7021.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r9CKrhs9020974; Sat, 12 Oct 2013 20:53:43 GMT In-Reply-To: <871u3qjq0j.fsf@yandex.ru> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.8 (707110) [OL 12.0.6680.5000 (x86)] X-Source-IP: ucsinet21.oracle.com [156.151.31.93] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 156.151.31.81 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:93964 Archived-At: > Consider this rather obvious higher-order function: > (defun addinator (a) (lambda (b) (+ a b))) >=20 > ;; This doesn't work with dynamic binding, at all > (funcall (addinator 3) 4) >=20 > ;; This returns wrong result with dynamic binding > (let ((a 42)) (funcall (addinator 3) 4)) Actually, both examples "work" with dynamic binding. They do exactly the code says they do. They simply work according to dynamic binding rules, not lexical binding rules. What is wrong is to expect lexical binding behavior without lexical binding! Both correctly raise an error if `a' has no value. `a' is a free variable in your examples, when using dynamic binding. and both work correctly, per dynamic binding behavior, if you first give `a' a value, e.g., (setq a 9). They just do not do what they would do with lexical binding; that's all. (setq a 9) ; Current dynamic value of `a' is 9. (defun addinator (a) (lambda (b) (+ a b))) ; That's (lambda (b) (+ a b)), a program that looks up ; `a' in the current dynamic environment, adds it to ; passed argument `b', and returns the result. (funcall (addinator 3) 4) ; That calls the result of (addinator 3) with argument 4. ; Which means it calls (lambda (b) (+ a b)) with arg 4. ; Which looks up the current dynamic binding of `a', which ; is 9, adds it to 4, and returns the result correctly: 13. (let ((a 42)) (funcall (addinator 3) 4)) ; That binds `a' to 42, changing the current dynamic binding ; of `a' to 42. Then it calls (addinator 3) with arg 4. ; Which adds the current dynamic binding of `a', which is 42, ; to `b'. The result is correct: 46. `addinator' has this definition: (lambda (a) (function (lambda (b) (+ a b)))) This is *not* a closure in Emacs Lisp. It is a function whose body is a *quoted* lambda expression that has a free variable, `a'. That free variable is looked up when that body function is applied, not when `addinator' is defined. The only thing wrong here is your mistaken expectation (and the attendant naming of function `addinator'). IOW, the error is in looking for noon at 2:00: "chercher midi =C3=A0 quator= ze heures". Yes, it can be confusing. No, dynamic binding is not very close to functional programming or lambda calculus. But it is not wrong. It just plays by different rules. Using Emacs Lisp, like using Common Lisp, requires understanding both kinds of behavior. Yes, one can choose not to use any dynamically scoped variables. Or one can choose not to use any lexically scoped variables. Such a choice can simplify what one needs to understand. "[I]t eliminates the problem of which variables lambda-expressions use (when they attempt to use variables from their surrounding context)." That elimination happens with either simplification: stick to dynamic-only or stick to lexical-only. The difference between the two eliminations is that with lexical scope you need only look at the immediate code; whereas with dynamic scope you need to think about time/state to understand the behavior. And yes, it is generally easier to determine lexical scope than dynamic scope: lexical means WYSIWYG. But the language provides both, and learning the language means understandi= ng both and how they can be used together.