From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Drew Adams Newsgroups: gmane.emacs.devel Subject: RE: Can't M-x compile-defun `edebug' because dynamic variables are falsely taken as lexical. Date: Fri, 14 Feb 2020 09:25:00 -0800 (PST) Message-ID: <9a1d6af0-7561-4679-930c-3bcda6169764@default> References: <20170103141444.GA4649@acm.fritz.box> <20170103213228.GB2085@acm.fritz.box> <20170104133948.GA7373@acm.fritz.box> <20170104200458.GA2052@acm.fritz.box> <29855ded-8607-4132-a80f-3204c06d74d9@default> <256f068f-5a0a-4127-aa7c-633eae24f15f@default> <837a062d-8fb0-4b41-bc53-d96a166263a4@default> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="2878"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Alan Mackenzie , emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Feb 14 18:26:21 2020 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1j2ejL-0000YR-LW for ged-emacs-devel@m.gmane-mx.org; Fri, 14 Feb 2020 18:26:19 +0100 Original-Received: from localhost ([::1]:42164 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j2ejK-0002WQ-Ne for ged-emacs-devel@m.gmane-mx.org; Fri, 14 Feb 2020 12:26:18 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:50650) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j2eiH-0001dV-S5 for emacs-devel@gnu.org; Fri, 14 Feb 2020 12:25:15 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j2eiD-00084f-5I for emacs-devel@gnu.org; Fri, 14 Feb 2020 12:25:13 -0500 Original-Received: from aserp2120.oracle.com ([141.146.126.78]:34288) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j2eiC-00083X-S1 for emacs-devel@gnu.org; Fri, 14 Feb 2020 12:25:09 -0500 Original-Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 01EHIstT183978; Fri, 14 Feb 2020 17:25:07 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2020-01-29; bh=XTuiTnqZjKNvJZcc4XZFqr7lLgdbNkriQa9PHJRMGZE=; b=oyVLjIBGHIYQlHoomKAoXMmtQBMDRJxgvFatGAL7xunWfBKSyUae/+gJ82ezkkFClTml Se8D1WTcY+0EWnWUucmS9rEzYri3p/4YIxHKFs7GeFUzxc/Igwmgb92iCaypdvBZrmsz FJVWBWZWdxzpzSzHq7yXHMWZoU+NLjAeN8JJLdnXF2zXDUyrExEOd6NvR+z5hdN/to4X FYKdKccE30I4V5x1JFVD1cE3ssDH+eX/8kvVxSe4KNewZ3FRuk7mOTM7RKmQrgZ5Gz6a j2Z6+5yenYuKQV+L7CXp4Vrn1Y4Ad14dVnMTOUM8Q3GtRNtsTXvYDBbRv1bTeZcp1wp+ 4w== Original-Received: from aserp3030.oracle.com (aserp3030.oracle.com [141.146.126.71]) by aserp2120.oracle.com with ESMTP id 2y2jx6twpt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 14 Feb 2020 17:25:06 +0000 Original-Received: from pps.filterd (aserp3030.oracle.com [127.0.0.1]) by aserp3030.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 01EHI0m1120979; Fri, 14 Feb 2020 17:25:06 GMT Original-Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserp3030.oracle.com with ESMTP id 2y4k82g196-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 14 Feb 2020 17:25:06 +0000 Original-Received: from abhmp0020.oracle.com (abhmp0020.oracle.com [141.146.116.26]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id 01EHP1IN031644; Fri, 14 Feb 2020 17:25:04 GMT In-Reply-To: X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4954.0 (x86)] X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9531 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 adultscore=0 suspectscore=0 mlxscore=0 bulkscore=0 malwarescore=0 phishscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2001150001 definitions=main-2002140130 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9531 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 malwarescore=0 priorityscore=1501 adultscore=0 phishscore=0 impostorscore=0 spamscore=0 bulkscore=0 lowpriorityscore=0 mlxscore=0 suspectscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2001150001 definitions=main-2002140130 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 141.146.126.78 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 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-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:244943 Archived-At: > > Permanently is not the opposite of locally. Instead > > of "permanently", shouldn't that text say "globally"? >=20 > Feel free to provide a patch that tries to clarify. That will have to come from someone who understands this better than I. I'm hoping to understand it a bit better from this thread, and then, hopefully, from an updated doc. > Part of the issue > is that (defvar VAR VAL) is just like (defvar VAR) when it's "processed" > by the byte-compiler: it won't affect bindings of VAR everywhere but > only within the corresponding lexical scope. But when (defvar VAR VAL) > is *executed* then it subsequently will affect all interpreted code and > all the code that is subsequently compiled in that same Emacs session, > whereas *executing* (defvar VAR VAL) only affects the code subsequently > interpreted, and only within the current lexical scope. I'm not sure how that relates to permanently vs globally, but OK, thanks. > >> if @var{value} is omitted then the variable is only > >> marked special locally (i.e.@: within the current > >> lexical scope, or file if at the top-level). > > This feature doesn't exist in Common Lisp, AFAIK. >=20 > AFAIK, in CL you can get something similar with > (declare (special foo)). Yes, similar, but not exactly the same. In CL, such a declaration can only be used, I think, within (certain) special forms. In particular, I don't think there's any equivalent for Emacs's file-local scope (other than putting the declaration in a top-level `let', or similar - a top-level `(locally (declare (special foo)))' perhaps). But maybe I'm wrong about this. The real point was about `defvar'. CL's `defvar' is not Emacs's, AFAIU. > > In CL, `defvar' always proclaims the variable special, > > whether or not an initial value is provided. >=20 > Indeed, Elisp is slightly different in this respect. The key word there is "proclaim". Function `proclaim': https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node104.html. "The function `proclaim' takes a DECL-SPEC as its argument and puts it into effect globally." "As a special case (so to speak), `proclaim' treats a `special' DECL-SPEC as applying to all bindings as well as to all references of the mentioned variables." "For example, after `(proclaim '(special x))' in a function definition such as `(defun example (x) ...)' the parameter X will be bound as a special (dynamic) variable rather than as a lexical (static) variable." That's what CL `defvar' does - it declares the var to be special, i.e., dynamic, everywhere. There's no shadowing (unlike the case for other proclamations). "`(defvar variable)' proclaims variable to be special (see `proclaim'), and may perform other system-dependent bookkeeping actions." https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node67.html > > And I think that for CL, a variable that is ever > > special is always and everywhere special, i.e., in > > all contexts. It's always bound dynamically. >=20 > In Common Lisp >=20 > (list > (lambda (x) > (let ((y x)) > (declare (special y)) > (lambda (z) (+ y z)))) > (lambda (x) > (let ((y x)) > (lambda (z) (+ y z))))) >=20 > gives you two functions that don't behave the same because the `y` > binding in the first is dynamically scoped whereas that same `y` > binding is statically scoped in the second. In CL parlance, those are not only not the same binding, they are not the same variable `y'. That's the point. The same symbol (name) is used for those two different `y' variables, but they're different vars (for CL). The first variable named `y' is special, which means that it's special everywhere (indefinite scope), and it's duration is the duration of the executing code that uses it (dynamic extent). > I'm saying that there's more to it than just either always or > never. E.g. in Common Lisp after the system has *compiled* a chunk of > code with (defvar VAR ...), VAR may or may not be special (i.e. the > `defvar` must have affected the compiled code, but not necessarily the > state of the system that compiled the file). Again, I think maybe you're thinking of VAR being occurrences of VAR as a symbol, as opposed to the variable that's declared ("created" in a sense, but not necessarily assigned a value - it might have no value, i.e., in CL-speak, be "unbound"). The effect on the compiled code gets to the use of the actual variable that was declared special. And yes, occurrences of other, different variables with the same name are not special. Not only "might not be special", but cannot be special - there is only ever one special variable with a given name. (Again, this is my understanding. It may be wrong.) > [ In Elisp, the situation is somewhat similar, tho a bit > less undefined. ] >=20 > >> Does Common Lisp offer something like `special-variable-p`? > > Not that I know of. >=20 > Indeed. And for good reasons: being a function it's hard to make it > provide the kind of semantic you expect from it, given the complexity > and scope-sensitivity of "specialness". I fully agree about that (as far as my understanding goes). =20 > > But it also doesn't use `defvar' with and without second arg to > > declare specialness. >=20 > That's just a superficial syntactic difference. >=20 > Maybe the slightly deeper difference is that Common Lisp doesn't have > a way to say "all bindings of VAR under the current scope should be > dynamic", like (defvar VAR) does. Instead it has (declare (special VAR)) > which only talks about one particular binding. I don't think that's right, but perhaps I don't follow you correctly. CL's `defvar' _proclaims_ the variable to be special (dynamic) - and the scope of that is indefinite - unlimited. It's not a lexical scope (this binding or this file). > But both Elisp's `defvar` and CL's `declare` introduce > the same issue that specialness is not all-or-nothing Dunno what that means, but I'm guessing that the difference in how we're talking about this is maybe the difference between how CL talks about a "variable". For the CL doc, a special variable is special everywhere - no lexical scoping for it at all, and its extent (lifetime) is dynamic. And as a consequence, there is only ever a single special variable with any given name (symbol). Its bindings are always dynamic. Its scope remains indefinite. > and that a plain function like `special-variable-p` > can't give quite the answer we'd ideally want. On that we agree. ___ Which brings us back to the beginning:=20 Maybe remove `special-variable-p' altogether? Or if, as is apparently the case, it's needed for the byte-compiler implementation, at least rename it to indicate that it's internal, and remove it from the manual? I'm not trying to remake the Emacs design of lexical scoping - or anything like that. I'm not even trying to change how it's presented in the doc (though maybe from this thread you'll have some slight changes you'd like to make). This is really only about `special-variable-p'. Both its name and its doc are currently quite misleading. And it doesn't seem like something that users will ever use or should ever try to use. I've asked about that use case...