From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Kelly Dean Newsgroups: gmane.emacs.devel Subject: Re: Why is Elisp's defvar weird? And is eval_sub broken? Date: Mon, 16 Feb 2015 05:42:38 +0000 Message-ID: References: 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 1424065473 7224 80.91.229.3 (16 Feb 2015 05:44:33 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 16 Feb 2015 05:44:33 +0000 (UTC) Cc: emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Feb 16 06:44:23 2015 Return-path: Envelope-to: ged-emacs-devel@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 1YNETm-0007CH-EG for ged-emacs-devel@m.gmane.org; Mon, 16 Feb 2015 06:44:22 +0100 Original-Received: from localhost ([::1]:37708 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YNETl-0004qK-Nh for ged-emacs-devel@m.gmane.org; Mon, 16 Feb 2015 00:44:21 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:57688) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YNETY-0004q4-R9 for emacs-devel@gnu.org; Mon, 16 Feb 2015 00:44:09 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YNETU-0000id-Qg for emacs-devel@gnu.org; Mon, 16 Feb 2015 00:44:08 -0500 Original-Received: from relay4-d.mail.gandi.net ([2001:4b98:c:538::196]:49475) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YNETU-0000gx-Kg for emacs-devel@gnu.org; Mon, 16 Feb 2015 00:44:04 -0500 Original-Received: from mfilter25-d.gandi.net (mfilter25-d.gandi.net [217.70.178.153]) by relay4-d.mail.gandi.net (Postfix) with ESMTP id 158AA172071; Mon, 16 Feb 2015 06:44:00 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at mfilter25-d.gandi.net Original-Received: from relay4-d.mail.gandi.net ([217.70.183.196]) by mfilter25-d.gandi.net (mfilter25-d.gandi.net [10.0.15.180]) (amavisd-new, port 10024) with ESMTP id Qg4eTWxD7OHA; Mon, 16 Feb 2015 06:43:58 +0100 (CET) X-Originating-IP: 66.220.3.179 Original-Received: from localhost (gm179.geneticmail.com [66.220.3.179]) (Authenticated sender: kelly@prtime.org) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id 4B652172055; Mon, 16 Feb 2015 06:43:55 +0100 (CET) In-Reply-To: X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:4b98:c:538::196 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:183144 Archived-At: Stefan Monnier wrote: >>> Normally, such conflicts should never happen >>> because all special vars should be named with a "package prefix", but >>> sadly, reality is different, so it was indispensable to make this >>> effect local, to allow lexical-binding code to work reliably. >> By using llet, the byte compiler will catch such conflicts, and your c= ode >> (interpreted or compiled) that uses it will work reliably despite the >> conflicts. This means defvar's weird behavior is no longer needed. > > It's not weird once you understand that it's a compiler directive which > is absent from the .elc file. If Elisp's defvar with no init value is used, then it avoids conflict, bu= t the packages that are a problem in the first place (by declaring non-pa= ckage-prefixed symbols special) will also be ones that tend to use defvar= _with_ an init value (so the symbols really are declared special, and th= eir defvars are in the elc). Elisp's defvar doesn't prevent conflict in t= hat case, so it seems the local-specialness feature doesn't fulfill its i= ntended purpose. In contrast, llet would prevent conflict in that case. (Global) specialness ambushes code that uses Lisp's standard =C2=ABlet=C2= =BB, because =C2=ABlet=C2=BB lets outside code decide how to bind the sym= bols. Elisp's local specialness just lets the outside code decline to lau= nch the ambush. In contrast, llet ensures that the ambush will fail. That= 's why it's the better solution. And it happens to be faster. And dlet is a faster way of doing what you can currently do in Elisp usin= g defvar (with no init value) followed by standard =C2=ABlet=C2=BB. Excep= t dlet causes only local dynamicness (called functions can read/set the v= ariables it binds), which is all it needs, not local specialness (makes f= ollowing =C2=ABlet=C2=BBs bind dynamically) like Elisp's defvar does. >> A declaration of free dynamic variables for a function could tell the >> byte compiler that those free variables aren't typos, since >> otherwise the byte compiler would expect either the symbol to be >> declared special or a lexical variable by that name to be in scope. > > There is such a declaration already. It's called (defvar ). Tada= ! Yes, though using defvar for this declaration in the function also causes= local specialness, when all that's needed in this case is just to tell t= he byte compiler that the variables aren't mistakes.