2

I have the following code:

#+begin_src elisp
(setq lexical-binding t)
(let ((a 1))                            ; binding (1)
  (let ((f (lambda () (print a))))
    (let ((a 2))                        ; binding (2)
      (funcall f)))) ; result: 2
#+end_src

Since I set lexical-binding to t, lexical bindings should be used instead of dynamic bindings. So I think the result of the above should be 1. But the result is 2. It's as if Emacs is still using dynamic bindings. Why? How can I make it use lexical bindings?

phils
  • 48,657
  • 3
  • 76
  • 115
Searene
  • 479
  • 2
  • 14

1 Answers1

5

Turn on the header :lexical, e.g.,

#+begin_src elisp :lexical t :results pp
(lambda ())
#+end_src

#+RESULTS:
: (closure
:  (t)
:  nil)

You can also use #+PROPERTY: header-args:elisp :lexical t to turn it on for the whole org file. Or change org-babel-default-header-args:emacs-lisp to turn it on globally.

(setq lexical-binding t) in the code does not work since it's too late, the scope (dynamic or lexical) is already decided BEFORE any of your code runs, hence to turn on lexical-binding, Emacs requires a special comment, which can be added via

M-x add-file-local-variable-prop-line lexical-binding t
xuchunyang
  • 14,302
  • 1
  • 18
  • 39
  • I’m interested to know how to make this work for elisp code that is tangled from org files. I have an org file that tangles to multiple elisp files, and the org file has the `#+PROPERTY` line set as you specified; but, none of the resulting elisp files contain the special `lexical-binding: t;` comment, nor are lambdas converted to closures or anything like that. Any ideas? – Tina Russell Mar 05 '21 at 02:19