I've seen ;;; -*- lexical-binding: t; -*-
at the top of a file and (setq lexical-binding t)
as how to turn on lexical binding for elisp code, but is there a way to tell Emacs to simply always do lexical binding, i.e., in your init file? From what I've seen, my guess would be it's a buffer-only option. Also, how can lexical binding be turned on in an org file? Does each babel emacs lisp code block have to specify (setq lexical-binding t)
? BTW, putting ;;; -*- lexical-binding: t; -*-
is not dealt with well on an export to HTML, etc. Using version 26.1.
1 Answer
Elisp
AFAIK the only two reliable ways for using lexical binding in Elisp files are:
Setting the buffer-local variable
lexical-binding
as file-local variable at the beginning of the Elisp file with
;;; -*- lexical-binding: t; -*-
Using
eval
with non-nilLEXICAL
argument. (LEXICAL
can be t or the lexical environment to be used)
Motivation for that behavior is that a global setting would potentially break your emacs configuration. Lexical binding in Elisp is a relatively new feature and older packages can rely on dynamic binding. See the difference in the behavior of lex-p
below for both variants of binding.
Org-mode
I don't know where you got (setq lexical-binding t)
from. That just does not work as the following Org source block shows:
#+BEGIN_SRC emacs-lisp
(setq lexical-binding t)
(defun lex-p ()
"Return t if lexical binding is in effect."
(let (lex
_lex-p)
(let ((lex t))
(setq _lex-p
(lambda ()
lex)))
(funcall _lex-p)))
(if (lex-p) "Yes" "No")
#+END_SRC
#+RESULTS:
: No
Nevertheless there is the header argument :lexical
for Org source block that just does what you want:
#+BEGIN_SRC emacs-lisp :lexical t
(defun lex-p ()
"Return t if lexical binding is in effect."
(let (lex
_lex-p)
(let ((lex t))
(setq _lex-p
(lambda ()
lex)))
(funcall _lex-p)))
(if (lex-p) "Yes" "No")
#+END_SRC
#+RESULTS:
: Yes
You can set that header argument file global by the header-args
property:
#+PROPERTY: header-args:emacs-lisp :lexical t
#+BEGIN_SRC emacs-lisp
(defun lex-p ()
"Return t if lexical binding is in effect."
(let (lex
_lex-p)
(let ((lex t))
(setq _lex-p
(lambda ()
lex)))
(funcall _lex-p)))
(if (lex-p) "Yes" "No")
#+END_SRC
#+RESULTS:
: Yes
#+BEGIN_SRC emacs-lisp
(if (lex-p) "Foo" "Bar")
#+END_SRC
#+RESULTS:
: Foo
-
Thanks, this makes sense. Still, in the second code block I see
#+BEGIN_SRC emacs-lisp :lexical t
but the next line is(setq lexical-binding t)
. You say above the second is ineffective? What was your thinking there?– 147pmMar 29, 2019 at 3:37 -
@147pm Thanks for the note. The presence of
(setq lexical-binding t)
in the second block was a copy-paste error. I have corrected it.– TobiasMar 29, 2019 at 3:47 -
(setq lexical-binding t)
is needed to use lexical-binding in*scratch*
.– npostavsMar 29, 2019 at 4:16 -
@npostavs if I put the code from the first code block into
*scratch*
, change the(if (lex-p) "Yes" "No")
into(message (if (lex-p) "Yes" "No"))
and evaluate the buffer withM-x eval-buffer
I get the message"No"
. On the other hand if I put the stuff from the second source block into the scratch buffer wrap the last form intomessage
and wrap everything by a(eval '(progn ...) t)
I get a"Yes"
.– TobiasMar 29, 2019 at 4:52 -
@npostavs Even more important: If I put the stuff from second source block into
*scratch*
with the last form wrapped in(message ...)
, insert;; -*- lexical-binding: t -*-
at the beginning of the buffer, and runM-x eval-buffer
I get a"Yes"
.– TobiasMar 29, 2019 at 5:03