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?

1

1 Answer 1

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
1
  • 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? Mar 5, 2021 at 2:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.