3 ms·
Many early lisps had dynamic scoping only. It meant that this code would return 5 (defvar x 1) ; new global var (defun foo () x) ; function returns x
by dan-robertson 5y ago
Many early lisps had dynamic scoping only. It meant that this code would return 5
(defvar x 1) ; new global var
(defun foo () x) ; function returns x
(+ (let ((x 4)) (foo)) (foo)) ; => 5
It also meant that anonymous functions weren’t closures. Later on, scheme used lexical scoping and Common Lisp used lexical scoping normally with dynamic scoping for special (typically global) variables like standard-input. At the time, implementers were worried that they wouldn’t be able to do lexical scoping efficiently.
Emacs lisp only had dynamic scoping for a long time. Furthermore it had buffer-local-variables where the editor has a notion of the current buffer, buffers can have definitions of variables, and the value you get for a variable depends on what it is bound to within that buffer as well as dynamically. Over time elisp got true closures/lexical scope, first via a library and later as a language feature (if a certain buffer-local variable is set when you compile/evaluate a file, you get lexical scoping; the easy way to set it is by writing a specially formatted line in the file which allows emacs to set ‘safe’ buffer local variables on opening the file.
- zelphirkalt 5y agoI knew, that Elisp got lexical scoping at some point, but do you know, whether package authors now use it often or maybe even more than dynamic scoping? Also thanks for the practical example of when it makes a difference!
- omaranto 5y ago> lexical scoping [...] do you know, whether package authors now use it often or maybe even more than dynamic scoping? All non-ancient packages use lexical scope. Most ancient packages anyone cared about were converted.