unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [PATCH] hack-one-local-variable use lexical-binding
@ 2020-11-26  2:55 Tom Gillespie
  2020-11-26  3:07 ` Stefan Monnier
  0 siblings, 1 reply; 11+ messages in thread
From: Tom Gillespie @ 2020-11-26  2:55 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2830 bytes --]

Hi,
   A small patch with a long preamble and a few questions about the
   best approach. Best!
Tom

=eval:= local variables currently cannot use lexical-binding

An example.

#+begin_src org
# -*- lexical-binding: t -*-
,#+name: code-block
,#+begin_src elisp :results none :lexical yes
(setq testv "no")
,#+end_src

Local Variables:
eval: (let ((testv "yes")) (org-sbe code-block) (message "%s" testv))
End:
#+end_src

There are two possible solutions. One is to pass t as LEXICAL at all
times. The other is to pass lexical-binding so that the behavior can
be controlled via =-*- lexical-binding: t -*-= on the prop line.

I'm not sure what the best approach is here. According to the manual
https://www.gnu.org/software/emacs/manual/html_node/elisp/Using-Lexical-Binding.html
other special evaluation contexts such as --eval, M-:, *scratch*, and
*ielm* have all already switched over to lexical binding by default.
Should local variables list eval variables follow the behavior of
these other special execution contexts? Or, since they are part of a
file should they follow the elisp file convention which is currently
to follow the lexical-binding local variable?

Despite personally having a use case for dynamic binding in this
context, from a sanity point of view I think setting LEXICAL to t at
all times may be the correct thing to do since with dynamic binding it
is possible for a function to overwrite a let bound variable in such a
way that the original value can never be recovered in the calling
scope.  However, that is sort of the point of dynamic binding, and it
would be a major breaking change to the default behavior, and it would
still not be configurable. Given that I also have no idea what the
actual impact of that change would be on users, using the local value
of lexical-binding seems to follow the principle of least surprise and
seems to be future proof if the default value of lexical-binding is
ever changed to t in the future (unlikely?).

One impact of this change is that =-*- lexical-binding: t -*-= on the
prop line will have meaning outside of Emacs lisp files and will have
meaning in any file that makes use of an =eval:= local variable.

As far as I can tell, passing =lexical-binding= works as expected.
=lexical-binding= needs to be set on the prop-line as usual, but can
also be set via an =eval:= local variable before any expression that
needs lexical binding in the local variables list. This is probably ok
because the use of =lexical-binding= in this context is not about the
evaluation of the current file, but rather about the evaluation of
further =eval:= local variables. Using =setq-local= to set
=lexical-binding= to =nil= in the strange case where someone wants
=lexical-binding= for their elisp file, but not when dealing with the
=eval:= local variables is also possible.

[-- Attachment #2: 0001-hack-one-local-variable-use-lexical-binding.patch --]
[-- Type: text/x-patch, Size: 829 bytes --]

From 5201892779738787a7dbe2d22735d2efb616597f Mon Sep 17 00:00:00 2001
From: Tom Gillespie <tgbugs@gmail.com>
Date: Wed, 25 Nov 2020 21:35:04 -0500
Subject: [PATCH] hack-one-local-variable use lexical-binding

* lisp/files.el (hack-one-local-variable): pass eval lexical-binding
---
 lisp/files.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lisp/files.el b/lisp/files.el
index 49c9e5d18d..c1c18ec58d 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -3984,7 +3984,7 @@ hack-one-local-variable
     ('eval
      (pcase val
        (`(add-hook ',hook . ,_) (hack-one-local-variable--obsolete hook)))
-     (save-excursion (eval val)))
+     (save-excursion (eval val lexical-binding)))
     (_
      (hack-one-local-variable--obsolete var)
      ;; Make sure the string has no text properties.
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-11-29 20:38 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-26  2:55 [PATCH] hack-one-local-variable use lexical-binding Tom Gillespie
2020-11-26  3:07 ` Stefan Monnier
2020-11-26  4:47   ` Tom Gillespie
2020-11-26  7:16     ` Eli Zaretskii
2020-11-26 14:21       ` Stefan Monnier
2020-11-26 14:44         ` Eli Zaretskii
2020-11-29  4:12           ` Tom Gillespie
2020-11-29  9:43           ` Stefan Kangas
2020-11-29 15:42             ` Eli Zaretskii
2020-11-29 19:50               ` Tom Gillespie
2020-11-29 20:38                 ` Stefan Monnier

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).