Describe lexical binding before dynamic

* doc/lispref/variables.texi (Variable Scoping)
(Lexical Binding, Dynamic Binding):
Alter the presentation order from the point of view that lexical
binding is the standard discipline (if not always the default) and
dynamic binding an alternative, which corresponds better to Elisp
today.  Modernise parts of the text.
* doc/lispref/elisp.texi (Top): Update menu.
This commit is contained in:
Mattias Engdegård 2023-10-21 17:39:25 +02:00
parent 48e7f5493e
commit 7e4a4b762e
2 changed files with 153 additions and 157 deletions

View file

@ -534,9 +534,9 @@ Variables
Scoping Rules for Variable Bindings
* Dynamic Binding:: The default for binding local variables in Emacs.
* Lexical Binding:: The standard type of local variable binding.
* Dynamic Binding:: A different type of local variable binding.
* Dynamic Binding Tips:: Avoiding problems with dynamic binding.
* Lexical Binding:: A different type of local variable binding.
* Using Lexical Binding:: How to enable lexical binding.
* Converting to Lexical Binding:: Convert existing code to lexical binding.

View file

@ -976,184 +976,57 @@ Variables}). This section describes exactly what this means.
binding can be accessed. @dfn{Extent} refers to @emph{when}, as the
program is executing, the binding exists.
@cindex lexical binding
@cindex lexical scope
@cindex indefinite extent
For historical reasons, there are two dialects of Emacs Lisp,
selected via the @code{lexical-binding} buffer-local variable.
In the modern Emacs Lisp dialect, local bindings are lexical by default.
A @dfn{lexical binding} has @dfn{lexical scope}, meaning that any
reference to the variable must be located textually within the binding
construct@footnote{With some exceptions; for instance, a lexical
binding can also be accessed from the Lisp debugger.}. It also has
@dfn{indefinite extent}, meaning that under some circumstances the
binding can live on even after the binding construct has finished
executing, by means of objects called @dfn{closures}.
@cindex dynamic binding
@cindex dynamic scope
@cindex dynamic extent
By default, the local bindings that Emacs creates are @dfn{dynamic
bindings}. Such a binding has @dfn{dynamic scope}, meaning that any
Local bindings can also be dynamic, which they always are in the
old Emacs Lisp dialect and optionally in the modern dialect.
A @dfn{dynamic binding} has @dfn{dynamic scope}, meaning that any
part of the program can potentially access the variable binding. It
also has @dfn{dynamic extent}, meaning that the binding lasts only
while the binding construct (such as the body of a @code{let} form) is
being executed.
@cindex lexical binding
@cindex lexical scope
@cindex indefinite extent
Emacs can optionally create @dfn{lexical bindings}. A lexical
binding has @dfn{lexical scope}, meaning that any reference to the
variable must be located textually within the binding
construct@footnote{With some exceptions; for instance, a lexical
binding can also be accessed from the Lisp debugger.}. It also has
@dfn{indefinite extent}, meaning that under some circumstances the
binding can live on even after the binding construct has finished
executing, by means of special objects called @dfn{closures}.
The old dynamic-only Emacs Lisp dialect is still the default in code
loaded or evaluated from Lisp files that lack a dialect declaration.
Eventually the modern dialect will be made the default.
All Lisp files should declare the dialect used to ensure that they
keep working correctly in the future.
The dynamic binding was (and still is) the default in Emacs for many
years, but lately Emacs is moving towards using lexical binding in
more and more places, with the goal of eventually making that the
default.
The following subsections describe dynamic binding and lexical
The following subsections describe lexical binding and dynamic
binding in greater detail, and how to enable lexical binding in Emacs
Lisp programs.
@menu
* Dynamic Binding:: The default for binding local variables in Emacs.
* Lexical Binding:: The standard type of local variable binding.
* Dynamic Binding:: A different type of local variable binding.
* Dynamic Binding Tips:: Avoiding problems with dynamic binding.
* Lexical Binding:: A different type of local variable binding.
* Using Lexical Binding:: How to enable lexical binding.
* Converting to Lexical Binding:: Convert existing code to lexical binding.
@end menu
@node Dynamic Binding
@subsection Dynamic Binding
By default, the local variable bindings made by Emacs are dynamic
bindings. When a variable is dynamically bound, its current binding
at any point in the execution of the Lisp program is simply the most
recently-created dynamic local binding for that symbol, or the global
binding if there is no such local binding.
Dynamic bindings have dynamic scope and extent, as shown by the
following example:
@example
@group
(defvar x -99) ; @r{@code{x} receives an initial value of @minus{}99.}
(defun getx ()
x) ; @r{@code{x} is used free in this function.}
(let ((x 1)) ; @r{@code{x} is dynamically bound.}
(getx))
@result{} 1
;; @r{After the @code{let} form finishes, @code{x} reverts to its}
;; @r{previous value, which is @minus{}99.}
(getx)
@result{} -99
@end group
@end example
@noindent
The function @code{getx} refers to @code{x}. This is a @dfn{free}
reference, in the sense that there is no binding for @code{x} within
that @code{defun} construct itself. When we call @code{getx} from
within a @code{let} form in which @code{x} is (dynamically) bound, it
retrieves the local value (i.e., 1). But when we call @code{getx}
outside the @code{let} form, it retrieves the global value (i.e.,
@minus{}99).
Here is another example, which illustrates setting a dynamically
bound variable using @code{setq}:
@example
@group
(defvar x -99) ; @r{@code{x} receives an initial value of @minus{}99.}
(defun addx ()
(setq x (1+ x))) ; @r{Add 1 to @code{x} and return its new value.}
(let ((x 1))
(addx)
(addx))
@result{} 3 ; @r{The two @code{addx} calls add to @code{x} twice.}
;; @r{After the @code{let} form finishes, @code{x} reverts to its}
;; @r{previous value, which is @minus{}99.}
(addx)
@result{} -98
@end group
@end example
Dynamic binding is implemented in Emacs Lisp in a simple way. Each
symbol has a value cell, which specifies its current dynamic value (or
absence of value). @xref{Symbol Components}. When a symbol is given
a dynamic local binding, Emacs records the contents of the value cell
(or absence thereof) in a stack, and stores the new local value in the
value cell. When the binding construct finishes executing, Emacs pops
the old value off the stack, and puts it in the value cell.
Note that when code using Dynamic Binding is native compiled the
native compiler will not perform any Lisp specific optimization.
@node Dynamic Binding Tips
@subsection Proper Use of Dynamic Binding
Dynamic binding is a powerful feature, as it allows programs to
refer to variables that are not defined within their local textual
scope. However, if used without restraint, this can also make
programs hard to understand. There are two clean ways to use this
technique:
@itemize @bullet
@item
If a variable has no global definition, use it as a local variable
only within a binding construct, such as the body of the @code{let}
form where the variable was bound. If this convention is followed
consistently throughout a program, the value of the variable will not
affect, nor be affected by, any uses of the same variable symbol
elsewhere in the program.
@item
Otherwise, define the variable with @code{defvar}, @code{defconst}
(@pxref{Defining Variables}), or @code{defcustom} (@pxref{Variable
Definitions}). Usually, the definition should be at top-level in an
Emacs Lisp file. As far as possible, it should include a
documentation string which explains the meaning and purpose of the
variable. You should also choose the variable's name to avoid name
conflicts (@pxref{Coding Conventions}).
Then you can bind the variable anywhere in a program, knowing reliably
what the effect will be. Wherever you encounter the variable, it will
be easy to refer back to the definition, e.g., via the @kbd{C-h v}
command (provided the variable definition has been loaded into Emacs).
@xref{Name Help,,, emacs, The GNU Emacs Manual}.
For example, it is common to use local bindings for customizable
variables like @code{case-fold-search}:
@example
@group
(defun search-for-abc ()
"Search for the string \"abc\", ignoring case differences."
(let ((case-fold-search t))
(re-search-forward "abc")))
@end group
@end example
@end itemize
@node Lexical Binding
@subsection Lexical Binding
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.
A lexically-bound variable has @dfn{lexical scope}, meaning that any
Lexical binding is only available in the modern Emacs Lisp dialect.
(@xref{Using Lexical Binding}.)
A lexically-bound variable has @dfn{lexical scope}, meaning that any
reference to the variable must be located textually within the binding
construct. Here is an example
@iftex
(see the next subsection, for how to actually enable lexical binding):
@end iftex
@ifnottex
(@pxref{Using Lexical Binding}, for how to actually enable lexical binding):
@end ifnottex
@example
@group
@ -1238,6 +1111,129 @@ functions which take a symbol argument (like @code{symbol-value},
variable's dynamic binding (i.e., the contents of its symbol's value
cell).
@node Dynamic Binding
@subsection Dynamic Binding
Local variable bindings are dynamic in the modern Lisp dialect for
special variables, and for all variables in the old Lisp
dialect. (@xref{Using Lexical Binding}.)
Dynamic variable bindings have their uses but are in general more
error-prone and less efficient than lexical bindings, and the compiler
is less able to find mistakes in code using dynamic bindings.
When a variable is dynamically bound, its current binding
at any point in the execution of the Lisp program is simply the most
recently-created dynamic local binding for that symbol, or the global
binding if there is no such local binding.
Dynamic bindings have dynamic scope and extent, as shown by the
following example:
@example
@group
(defvar x -99) ; @r{@code{x} receives an initial value of @minus{}99.}
(defun getx ()
x) ; @r{@code{x} is used free in this function.}
(let ((x 1)) ; @r{@code{x} is dynamically bound.}
(getx))
@result{} 1
;; @r{After the @code{let} form finishes, @code{x} reverts to its}
;; @r{previous value, which is @minus{}99.}
(getx)
@result{} -99
@end group
@end example
@noindent
The function @code{getx} refers to @code{x}. This is a @dfn{free}
reference, in the sense that there is no binding for @code{x} within
that @code{defun} construct itself. When we call @code{getx} from
within a @code{let} form in which @code{x} is (dynamically) bound, it
retrieves the local value (i.e., 1). But when we call @code{getx}
outside the @code{let} form, it retrieves the global value (i.e.,
@minus{}99).
Here is another example, which illustrates setting a dynamically
bound variable using @code{setq}:
@example
@group
(defvar x -99) ; @r{@code{x} receives an initial value of @minus{}99.}
(defun addx ()
(setq x (1+ x))) ; @r{Add 1 to @code{x} and return its new value.}
(let ((x 1))
(addx)
(addx))
@result{} 3 ; @r{The two @code{addx} calls add to @code{x} twice.}
;; @r{After the @code{let} form finishes, @code{x} reverts to its}
;; @r{previous value, which is @minus{}99.}
(addx)
@result{} -98
@end group
@end example
Dynamic binding is implemented in Emacs Lisp in a simple way. Each
symbol has a value cell, which specifies its current dynamic value (or
absence of value). @xref{Symbol Components}. When a symbol is given
a dynamic local binding, Emacs records the contents of the value cell
(or absence thereof) in a stack, and stores the new local value in the
value cell. When the binding construct finishes executing, Emacs pops
the old value off the stack, and puts it in the value cell.
@node Dynamic Binding Tips
@subsection Proper Use of Dynamic Binding
Dynamic binding is a powerful feature, as it allows programs to
refer to variables that are not defined within their local textual
scope. However, if used without restraint, this can also make
programs hard to understand. There are two clean ways to use this
technique:
@itemize @bullet
@item
If a variable has no global definition, use it as a local variable
only within a binding construct, such as the body of the @code{let}
form where the variable was bound. If this convention is followed
consistently throughout a program, the value of the variable will not
affect, nor be affected by, any uses of the same variable symbol
elsewhere in the program.
@item
Otherwise, define the variable with @code{defvar}, @code{defconst}
(@pxref{Defining Variables}), or @code{defcustom} (@pxref{Variable
Definitions}). Usually, the definition should be at top-level in an
Emacs Lisp file. As far as possible, it should include a
documentation string which explains the meaning and purpose of the
variable. You should also choose the variable's name to avoid name
conflicts (@pxref{Coding Conventions}).
Then you can bind the variable anywhere in a program, knowing reliably
what the effect will be. Wherever you encounter the variable, it will
be easy to refer back to the definition, e.g., via the @kbd{C-h v}
command (provided the variable definition has been loaded into Emacs).
@xref{Name Help,,, emacs, The GNU Emacs Manual}.
For example, it is common to use local bindings for customizable
variables like @code{case-fold-search}:
@example
@group
(defun search-for-abc ()
"Search for the string \"abc\", ignoring case differences."
(let ((case-fold-search t))
(re-search-forward "abc")))
@end group
@end example
@end itemize
@node Using Lexical Binding
@subsection Using Lexical Binding