2

Suppose you save the following code to some file test.el and then do load-file test.el

;;; -*- lexical-binding: t -*-

(let ((closure-vbl 0))
  (defun tst ()
    (eval 'closure-vbl)))

(tst)

You get the error tst: Symbol's value as variable is void: closure-vbl. (Replacing (eval 'closure-vbl) with (symbol-function 'closure-vbl) gives the same error.)

Why is this? I don't understand what is wrong with the above code? Am I miunderstanding some property of emacs closures? Or are they simply not developed enough to deal with non-trivial situations.

4

There's a few pitfalls here:

  • Using eval with lexical-binding will fail unless you pass it an alist environment argument holding the bindings in question (see F1 f eval)
  • Looking up symbol slots only behaves correctly with dynamic scoping, if you attempt it despite this, you'll get the global value (see F1 f symbol-value)

FWIW, this is what I'd call the straight-forward use:

;; -*- lexical-binding: t; -*-

(let ((closure-variable 0))
  (defun test ()
    closure-variable))

(test)
  • 1
    Is there any way to get the lexical environment in a function? More generally, is it ever possible to indirectly refer to a lexically-scoped variable? Something like the following also fails: (defun tst3 (vbl) (eval 'vbl t)) (Here, I've tried using the LEXICAL flag on eval but it doesn't seem to help.) – Jonathan Ganc Jan 24 '17 at 8:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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