Subject: bug#66756: closed (Re: bug#66756: 30.0.50; [PATCH] Improve discussion of 'let' in Elisp Introduction manual)

From: [email-masked] (GNU bug Tracking System)
Date: Tue, 09 Jan 2024 18:42:03 +0000

Your bug report

#66756: 30.0.50; [PATCH] Improve discussion of 'let' in Elisp Introduction manual

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
66756: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=66756
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#66756: 30.0.50; [PATCH] Improve discussion of 'let' in Elisp Introduction manual
From: Jim Porter <[email-masked]>
To: Stefan Kangas <[email-masked]>, [email-masked]
Cc: [email-masked], [email-masked]
Date: Tue, 9 Jan 2024 10:40:47 -0800
List-Id: <debbugs-submit.debbugs.gnu.org>

Version: 29.2

On 12/17/2023 12:47 PM, Jim Porter wrote:
> On 12/16/2023 3:10 PM, Stefan Kangas wrote:
>> Jim Porter <[email-masked]> writes:
>>
>> I suggest merging it to emacs-29.  If we indeed think it's better, let's
>> get the improved documentation into users' hands.
> 
> Sounds good to me. I'll give people another day or two to raise any last 
> concerns, and if there aren't any, I'll merge to the 29 branch.

I've now merged the latest revision of my patch to the release branch as 
d58d0fa52ff. Closing this bug.

Of course, if anyone sees any further issues, just let me know and I'll 
try to address them.

Subject: 30.0.50; [PATCH] Improve discussion of 'let' in Elisp Introduction manual
From: Jim Porter <[email-masked]>
To: [email-masked]
Date: Wed, 25 Oct 2023 22:54:25 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

(Spun out from bug#66706. My previous message below.)

On 10/25/2023 8:48 PM, Jim Porter wrote:
 > On 10/25/2023 6:19 PM, Jim Porter wrote:
 >> I'll start with a patch here then. I think this is also a prime spot
 >> to add an example or two that would actually show lexical binding in
 >> action (i.e. a sample where the code would do something different
 >> under dynamic binding).
 >
 > Here's a first attempt. I'm not sure I'm entirely happy with it (the
 > digression into setting 'lexical-binding' to 't' is a bit disruptive),
 > but hopefully it's an improvement. Of course, we can keep adjusting this
 > further as needed.

From 6bc9bbbb98105f700bb8d5b04e8de5e261efa777 Mon Sep 17 00:00:00 2001
From: Jim Porter <[email-masked]>
Date: Wed, 25 Oct 2023 20:43:57 -0700
Subject: [PATCH] Introduce 'let' using lexical binding in the Lisp
 Introduction

* doc/lispintro/emacs-lisp-intro.texi (Prevent confusion): Rename to...
(Why Use let?): ... this, and rework the explanation to discuss
lexical binding (including how to enable it).
---
 doc/lispintro/emacs-lisp-intro.texi | 81 +++++++++++++++++++++--------
 1 file changed, 58 insertions(+), 23 deletions(-)

diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index fce7583fe91..ebbcc08b9ff 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -3587,39 +3587,74 @@ let
 @code{let} special form prevents this kind of confusion.
 
 @menu
-* Prevent confusion::
+* Why Use let?::
 * Parts of let Expression::
 * Sample let Expression::
 * Uninitialized let Variables::
 @end menu
 
 @ifnottex
-@node Prevent confusion
-@unnumberedsubsec @code{let} Prevents Confusion
+@node Why Use let?
+@unnumberedsubsec Why Use @code{let}?
 @end ifnottex
 
 @cindex @samp{local variable} defined
 @cindex @samp{variable, local}, defined
-The @code{let} special form prevents confusion.  @code{let} creates a
-name for a @dfn{local variable} that overshadows any use of the same
-name outside the @code{let} expression.  This is like understanding
-that whenever your host refers to ``the house'', he means his house, not
-yours.  (Symbols used in argument lists work the same way.
-@xref{defun, , The @code{defun} Macro}.)
-
-Local variables created by a @code{let} expression retain their value
-@emph{only} within the @code{let} expression itself (and within
-expressions called within the @code{let} expression); the local
-variables have no effect outside the @code{let} expression.
-
-Another way to think about @code{let} is that it is like a @code{setq}
-that is temporary and local.  The values set by @code{let} are
-automatically undone when the @code{let} is finished.  The setting
-only affects expressions that are inside the bounds of the @code{let}
-expression.  In computer science jargon, we would say the binding of
-a symbol is visible only in functions called in the @code{let} form;
-in Emacs Lisp, the default scoping is dynamic, not lexical.  (The
-non-default lexical binding is not discussed in this manual.)
+The @code{let} special form provides a way to confine your variables
+to a particular section of your code (in computer science jargon, a
+``scope'').  @code{let} creates a name for a @dfn{local variable} that
+overshadows any use of the same name outside the @code{let} expression
+(we call this ``binding'' the variable).  This prevents any accidental
+usage of these variables outside of the @code{let} expression.  This
+is like understanding that whenever your host refers to ``the house'',
+he means his house, not yours.  (Symbols used in argument lists work
+the same way.  @xref{defun, , The @code{defun} Macro}.)
+
+@cindex lexical binding
+@cindex binding, lexical
+@cindex dynamic binding
+@cindex binding, dynamic
+Before we begin discussing @code{let} in detail, we must first mention
+an important note.  For historical reasons, Emacs Lisp uses a form of
+variable binding called ``dynamic binding''.  However, this manual
+will discuss the preferred form of binding, called ``lexical binding''
+(if you have programmed in other languages before, you're likely
+already familiar with how lexical binding behaves).  In order to use
+lexical binding, you should add something like this to the first line
+of your Emacs Lisp file:
+
+@example
+;;; -*- lexical-binding: t -*-
+@end example
+
+For more information about this, @pxref{Selecting Lisp Dialect, , ,
+elisp, The Emacs Lisp Reference Manual}.
+
+With that out of the way, we can return to discussing @code{let}.
+Local variables created by a @code{let} expression hold their value
+@emph{only} within the body of the @code{let} expression itself; the
+local variables have no effect outside of the @code{let} expression.
+This means that inside the @code{let} body, calling @code{setq}
+for a variable named by the @code{let} expression will set the value
+of the @emph{local} variable of that name.  This also means that
+outside of the @code{let} body, calling @code{setq} for a variable
+named by the @code{let} expression will @emph{not} affect that local
+variable.
+
+For example, if you call a function inside of a @code{let}
+body, that function's body would be unable to ``see'' (or modify) the
+value of a local variable from the @code{let} expression:
+
+@example
+(setq x 1)
+
+(defun getx ()
+  x)
+
+(let ((x 2))
+  (get-x))
+     @result{} 1
+@end example
 
 @code{let} can create more than one variable at once.  Also,
 @code{let} gives each variable it creates an initial value, either a
-- 
2.25.1