eintr: fwd-sentence while loops

 
 The ‘while’ loops
 -----------------
 
 Two ‘while’ loops follow.  The first ‘while’ has a true-or-false-test
 that tests true if the prefix argument for ‘forward-sentence’ is a
 negative number.  This is for going backwards.  The body of this loop is
 similar to the body of the second ‘while’ clause, but it is not exactly
 the same.  We will skip this ‘while’ loop and concentrate on the second
 ‘while’ loop.
 
    The second ‘while’ loop is for moving point forward.  Its skeleton
 looks like this:
 
      (while (> arg 0)            ; true-or-false-test
        (let VARLIST
          (if (TRUE-OR-FALSE-TEST)
              THEN-PART
            ELSE-PART
        (setq arg (1- arg))))     ; while loop decrementer
 
    The ‘while’ loop is of the decrementing kind.  (SeeA Loop with a
 Decrementing Counter Decrementing Loop.)  It has a true-or-false-test
 that tests true so long as the counter (in this case, the variable
 ‘arg’) is greater than zero; and it has a decrementer that subtracts 1
 from the value of the counter every time the loop repeats.
 
    If no prefix argument is given to ‘forward-sentence’, which is the
 most common way the command is used, this ‘while’ loop will run once,
 since the value of ‘arg’ will be 1.
 
    The body of the ‘while’ loop consists of a ‘let’ expression, which
 creates and binds a local variable, and has, as its body, an ‘if’
 expression.
 
    The body of the ‘while’ loop looks like this:
 
      (let ((par-end
             (save-excursion (end-of-paragraph-text) (point))))
        (if (re-search-forward sentence-end par-end t)
            (skip-chars-backward " \t\n")
          (goto-char par-end)))
 
    The ‘let’ expression creates and binds the local variable ‘par-end’.
 As we shall see, this local variable is designed to provide a bound or
 limit to the regular expression search.  If the search fails to find a
 proper sentence ending in the paragraph, it will stop on reaching the
 end of the paragraph.
 
    But first, let us examine how ‘par-end’ is bound to the value of the
 end of the paragraph.  What happens is that the ‘let’ sets the value of
 ‘par-end’ to the value returned when the Lisp interpreter evaluates the
 expression
 
      (save-excursion (end-of-paragraph-text) (point))
 
 In this expression, ‘(end-of-paragraph-text)’ moves point to the end of
 the paragraph, ‘(point)’ returns the value of point, and then
 ‘save-excursion’ restores point to its original position.  Thus, the
 ‘let’ binds ‘par-end’ to the value returned by the ‘save-excursion’
 expression, which is the position of the end of the paragraph.  (The
 ‘end-of-paragraph-text’ function uses ‘forward-paragraph’, which we will
 discuss shortly.)
 
    Emacs next evaluates the body of the ‘let’, which is an ‘if’
 expression that looks like this:
 
      (if (re-search-forward sentence-end par-end t) ; if-part
          (skip-chars-backward " \t\n")              ; then-part
        (goto-char par-end)))                        ; else-part
 
    The ‘if’ tests whether its first argument is true and if so,
 evaluates its then-part; otherwise, the Emacs Lisp interpreter evaluates
 the else-part.  The true-or-false-test of the ‘if’ expression is the
 regular expression search.
 
    It may seem odd to have what looks like the real work of the
 ‘forward-sentence’ function buried here, but this is a common way this
 kind of operation is carried out in Lisp.