1

I've been reading about emacs dynamic and lexical bindings. While I generally get the difference between the two types, there is one example that is not clear to me. I've checked this question and I think I understand why the second example prints nil instead of t (I've read about set and setq when lexical-binding: t

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

(let ((a nil))
  (setq a t)
  (print a))


(let ((a nil))
  (set 'a t)
  (print a))

From the elisp manual I've read that when lexical-binding is in effect set affects the dynamic value of a variable where as setq affects its current lexical value. However from the following example it looks like (setq a 5) sets the dynamic value of a since later (set 'a t) changes top level a.

;;; -*- lexical-binding: t; -*-
(setq a 5)

(let ((a nil))
  (setq a t)
  (print a)) ;; prints t 


(let ((a nil))
  (set 'a t)
  (print a)) ;; prints nil

a ;; prints t (I've expected this to be unchanged i.e. 5)

My question is when lexical-binding is on, what is the binding for the top level variables ?

Ivan Ruski
  • 111
  • 2

1 Answers1

2

Looking at Using Lexical Binding it appears that a needs to be defined special which in using setq it is not. Modifying your example to use defvar gives the answers expected.

;;; -*- lexical-binding: t; -*-
(defvar b 5)

(let ((b nil))
  (setq b t)
  (print b)) ;; prints t 

(print b) ;; prints 5

(let ((b nil))
  (set 'b t)
  (print b)) ;; prints t

(print b) ;; prints 5
alls0rts
  • 346
  • 3
  • 9
  • 1
    Yes. With lexical binding as the default (from non-nil variable `lexical-binding`), unless a variable is declared (e.g. with `defvar`) to be special (aka dynamic), it is only and always lexically bound (and if *set* at top level that's treated as a lexical binding also). – Drew Mar 24 '21 at 15:37
  • I see, thanks a lot the answer. What about `set` ? In the [doc](https://www.gnu.org/software/emacs/manual/html_node/elisp/Setting-Variables.html) they say that set affects the symbol's _dynamic_ value, but from [this](https://gist.githubusercontent.com/ivanruski/cd17650c7c2201fc9c1354c71d23841d/raw/9c68ed85f78692dc1002d9caaf25367f158126ef/scratch.el) example it seems to me that the _dynamic_ value and the value of a top level variable is the same thing. Is that correct ? – Ivan Ruski Mar 25 '21 at 21:00
  • The example in the doc is `(set 'one 3) ; not the global value`. Appending one final (gety) outside of the `let` in your example confirms that the external `y` is still 5, and in the evaluation in Emacs with your example the results are 7, 8, 9, 7! – alls0rts Apr 02 '21 at 15:20