emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] hack-one-local-variable use lexical-binding


From: Tom Gillespie
Subject: [PATCH] hack-one-local-variable use lexical-binding
Date: Wed, 25 Nov 2020 21:55:08 -0500

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: 0001-hack-one-local-variable-use-lexical-binding.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]