Copyright (C) 2000-2012 |
GNU Info (cl)Lexical BindingsLexical Bindings ---------------- The "CL" package defines the following macro which more closely follows the Common Lisp `let' form: - Special Form: lexical-let (bindings...) forms... This form is exactly like `let' except that the bindings it establishes are purely lexical. Lexical bindings are similar to local variables in a language like C: Only the code physically within the body of the `lexical-let' (after macro expansion) may refer to the bound variables. (setq a 5) (defun foo (b) (+ a b)) (let ((a 2)) (foo a)) => 4 (lexical-let ((a 2)) (foo a)) => 7 In this example, a regular `let' binding of `a' actually makes a temporary change to the global variable `a', so `foo' is able to see the binding of `a' to 2. But `lexical-let' actually creates a distinct local variable `a' for use within its body, without any effect on the global variable of the same name. The most important use of lexical bindings is to create "closures". A closure is a function object that refers to an outside lexical variable. For example: (defun make-adder (n) (lexical-let ((n n)) (function (lambda (m) (+ n m))))) (setq add17 (make-adder 17)) (funcall add17 4) => 21 The call `(make-adder 17)' returns a function object which adds 17 to its argument. If `let' had been used instead of `lexical-let', the function object would have referred to the global `n', which would have been bound to 17 only during the call to `make-adder' itself. (defun make-counter () (lexical-let ((n 0)) (function* (lambda (&optional (m 1)) (incf n m))))) (setq count-1 (make-counter)) (funcall count-1 3) => 3 (funcall count-1 14) => 17 (setq count-2 (make-counter)) (funcall count-2 5) => 5 (funcall count-1 2) => 19 (funcall count-2) => 6 Here we see that each call to `make-counter' creates a distinct local variable `n', which serves as a private counter for the function object that is returned. Closed-over lexical variables persist until the last reference to them goes away, just like all other Lisp objects. For example, `count-2' refers to a function object which refers to an instance of the variable `n'; this is the only reference to that variable, so after `(setq count-2 nil)' the garbage collector would be able to delete this instance of `n'. Of course, if a `lexical-let' does not actually create any closures, then the lexical variables are free as soon as the `lexical-let' returns. Many closures are used only during the extent of the bindings they refer to; these are known as "downward funargs" in Lisp parlance. When a closure is used in this way, regular Emacs Lisp dynamic bindings suffice and will be more efficient than `lexical-let' closures: (defun add-to-list (x list) (mapcar (lambda (y) (+ x y))) list) (add-to-list 7 '(1 2 5)) => (8 9 12) Since this lambda is only used while `x' is still bound, it is not necessary to make a true closure out of it. You can use `defun' or `flet' inside a `lexical-let' to create a named closure. If several closures are created in the body of a single `lexical-let', they all close over the same instance of the lexical variable. The `lexical-let' form is an extension to Common Lisp. In true Common Lisp, all bindings are lexical unless declared otherwise. - Special Form: lexical-let* (bindings...) forms... This form is just like `lexical-let', except that the bindings are made sequentially in the manner of `let*'. automatically generated by info2www version 1.2.2.9 |