summaryrefslogtreecommitdiff
path: root/devdocs/elisp/lexical-binding.html
diff options
context:
space:
mode:
Diffstat (limited to 'devdocs/elisp/lexical-binding.html')
-rw-r--r--devdocs/elisp/lexical-binding.html38
1 files changed, 38 insertions, 0 deletions
diff --git a/devdocs/elisp/lexical-binding.html b/devdocs/elisp/lexical-binding.html
new file mode 100644
index 00000000..7e07562b
--- /dev/null
+++ b/devdocs/elisp/lexical-binding.html
@@ -0,0 +1,38 @@
+ <h4 class="subsection">Lexical Binding</h4> <p>Lexical binding was introduced to Emacs, as an optional feature, in version 24.1. We expect its importance to increase with time. Lexical binding opens up many more opportunities for optimization, so programs using it are likely to run faster in future Emacs versions. Lexical binding is also more compatible with concurrency, which was added to Emacs in version 26.1. </p> <p>A lexically-bound variable has <em>lexical scope</em>, meaning that any reference to the variable must be located textually within the binding construct. Here is an example (see <a href="using-lexical-binding">Using Lexical Binding</a>, for how to actually enable lexical binding): </p> <div class="example"> <pre class="example">(let ((x 1)) ; <span class="roman"><code>x</code> is lexically bound.</span>
+ (+ x 3))
+ ⇒ 4
+
+(defun getx ()
+ x) ; <span class="roman"><code>x</code> is used free in this function.</span>
+
+(let ((x 1)) ; <span class="roman"><code>x</code> is lexically bound.</span>
+ (getx))
+error→ Symbol's value as variable is void: x
+</pre>
+</div> <p>Here, the variable <code>x</code> has no global value. When it is lexically bound within a <code>let</code> form, it can be used in the textual confines of that <code>let</code> form. But it can <em>not</em> be used from within a <code>getx</code> function called from the <code>let</code> form, since the function definition of <code>getx</code> occurs outside the <code>let</code> form itself. </p> <p>Here is how lexical binding works. Each binding construct defines a <em>lexical environment</em>, specifying the variables that are bound within the construct and their local values. When the Lisp evaluator wants the current value of a variable, it looks first in the lexical environment; if the variable is not specified in there, it looks in the symbol’s value cell, where the dynamic value is stored. </p> <p>(Internally, the lexical environment is an alist of symbol-value pairs, with the final element in the alist being the symbol <code>t</code> rather than a cons cell. Such an alist can be passed as the second argument to the <code>eval</code> function, in order to specify a lexical environment in which to evaluate a form. See <a href="eval">Eval</a>. Most Emacs Lisp programs, however, should not interact directly with lexical environments in this way; only specialized programs like debuggers.) </p> <p>Lexical bindings have indefinite extent. Even after a binding construct has finished executing, its lexical environment can be “kept around” in Lisp objects called <em>closures</em>. A closure is created when you define a named or anonymous function with lexical binding enabled. See <a href="closures">Closures</a>, for details. </p> <p>When a closure is called as a function, any lexical variable references within its definition use the retained lexical environment. Here is an example: </p> <div class="example"> <pre class="example">(defvar my-ticker nil) ; <span class="roman">We will use this dynamically bound</span>
+ ; <span class="roman">variable to store a closure.</span>
+
+(let ((x 0)) ; <span class="roman"><code>x</code> is lexically bound.</span>
+ (setq my-ticker (lambda ()
+ (setq x (1+ x)))))
+ ⇒ (closure ((x . 0) t) ()
+ (setq x (1+ x)))
+
+(funcall my-ticker)
+ ⇒ 1
+
+(funcall my-ticker)
+ ⇒ 2
+
+(funcall my-ticker)
+ ⇒ 3
+
+x ; <span class="roman">Note that <code>x</code> has no global value.</span>
+error→ Symbol's value as variable is void: x
+</pre>
+</div> <p>The <code>let</code> binding defines a lexical environment in which the variable <code>x</code> is locally bound to 0. Within this binding construct, we define a lambda expression which increments <code>x</code> by one and returns the incremented value. This lambda expression is automatically turned into a closure, in which the lexical environment lives on even after the <code>let</code> binding construct has exited. Each time we evaluate the closure, it increments <code>x</code>, using the binding of <code>x</code> in that lexical environment. </p> <p>Note that unlike dynamic variables which are tied to the symbol object itself, the relationship between lexical variables and symbols is only present in the interpreter (or compiler). Therefore, functions which take a symbol argument (like <code>symbol-value</code>, <code>boundp</code>, and <code>set</code>) can only retrieve or modify a variable’s dynamic binding (i.e., the contents of its symbol’s value cell). </p><div class="_attribution">
+ <p class="_attribution-p">
+ Copyright &copy; 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br>
+ <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html</a>
+ </p>
+</div>