;; ;; This is an Emacs LISP buffer, saved in lisp-interaction-mode. ;; By default, Emacs uses dynamic binding/scoping, but, since Emacs 24, ;; it can be switched (per-buffer) to use lexical scoping. ;; Switching to lexical-binding changes bytecode generated for ;; functions. More about Emacs bytecode: http://nullprogram.com/blog/2014/01/04/ ;; ;; More about lexical scoping in Emacs 24: http://prog-elisp.blogspot.com/2012/05/lexical-scope.html (+ 1 3) 4 (defun sc-test (x) (list x y)) sc-test (sc-test 5) ; this fails: y is unbound ;; Unlike Common Lisp, there's no "closure" over y in let: ;; y in sc-test gets whatever value it currently has, ;; locally in let or globally. (let ((y 100)) (sc-test 5)) (5 100) (setq y 2000) 2000 (sc-test 5) (5 2000) (let ((y 5000)) (sc-test 5)) (5 5000) (sc-test 6) (6 2000) (let ((y 7)) (defun sc-test (x) (list x y))) sc-test (sc-test 2) (2 2000) y 2000 (disassemble 'sc-test) nil --------- Pasted from another buffer: --------- byte code for sc-test: args: (x) 0 varref x 1 varref y 2 list2 3 return --------- end paste --------- (disassemble '(defun l () (list 1 2 3))) ;; just an example what what bytecode looks like nil --------- Pasted from another buffer: --------- byte code: args: nil 0 constant defalias 1 constant l 2 constant args: nil 0 constant 1 1 constant 2 2 constant 3 3 list3 4 return 3 call 2 4 return --------- end paste --------- lexical-binding nil ;; Set scope to lexical. Now closures will happen. (setq lexical-binding t) t (let ((y 7)) (defun sc-test1 (x) (list x y))) sc-test1 (sc-test1 3) (3 7) (let ((y 4)) (sc-test1 100)) (100 7) (setq y 10000) 10000 (sc-test1 1) (1 7) ;; <-- Still 7. sc-test1 "closed" over the local y with which it was created. ;; sc-test is till unclosed (sc-test 1) (1 10000) (disassemble (symbol-function 'sc-test1)) nil --------- Pasted from another buffer: --------- byte code: args: nil 0 constant closure 1 constant (y . 7) 2 constant t 3 call 1 4 constant x 5 call 0 6 varref x 7 varref y 8 list2 9 call 3 10 return --------- end pasted ---------