commit ac6ad05973606e7aa034ba7efe231d4c74971a96
parent 63f6ad27b398ce1a2331039444230acc53358865
Author: Wolfgang Corcoran-Mathe <wcm@sigwinch.xyz>
Date: Sun, 4 Feb 2024 21:45:04 -0500
Control features: Reflow.
Diffstat:
1 file changed, 168 insertions(+), 167 deletions(-)
diff --git a/doc/r7rs-small/procedures/control-features.texinfo b/doc/r7rs-small/procedures/control-features.texinfo
@@ -1,9 +1,10 @@
@node Control features
@section Control features
-This section describes various primitive procedures which control the flow of program
-execution in special ways. Procedures in this section that invoke procedure arguments
-always do so in the same dynamic environment as the call of the original procedure. The
+This section describes various primitive procedures which control
+the flow of program execution in special ways. Procedures in this
+section that invoke procedure arguments always do so in the same
+dynamic environment as the call of the original procedure. The
@code{procedure?} predicate is also described here.
@deffn procedure procedure? obj
@@ -26,8 +27,9 @@ Returns @code{#t} if
@deffn procedure apply proc @vari{arg}@dots{} args
-The @code{apply} procedure calls
-@var{proc} with the elements of the list @code{(append (list }@vari{arg} @dots{}@code{) args)} as the actual arguments.
+The @code{apply} procedure calls @var{proc} with the elements of the
+list @code{(append (list }@vari{arg} @dots{}@code{) args)} as the
+actual arguments.
@lisp
(apply + (list 3 4)) @result{} 7
@@ -44,19 +46,18 @@ The @code{apply} procedure calls
@deffn procedure map proc @vari{list} @varii{list}@dots{}
-It is an error if @var{proc} does not
-accept as many arguments as there are @var{list}s
-and return a single value.
+It is an error if @var{proc} does not accept as many arguments as
+there are @var{list}s and return a single value.
-The @code{map} procedure applies @var{proc} element-wise to the elements of the
-@var{list}s and returns a list of the results, in order.
-If more than one @var{list} is given and not all lists have the same length,
-@code{map} terminates when the shortest list runs out.
-The @var{list}s can be circular, but it is an error if all of them are circular.
-It is an error for @var{proc} to mutate any of the lists.
-The dynamic order in which @var{proc} is applied to the elements of the
-@var{list}s is unspecified. If multiple returns occur from @code{map},
-the values returned by earlier returns are not mutated.
+The @code{map} procedure applies @var{proc} element-wise to the
+elements of the @var{list}s and returns a list of the results, in
+order. If more than one @var{list} is given and not all lists have
+the same length, @code{map} terminates when the shortest list runs out.
+The @var{list}s can be circular, but it is an error if all of them are
+circular. It is an error for @var{proc} to mutate any of the lists.
+The dynamic order in which @var{proc} is applied to the elements
+of the @var{list}s is unspecified. If multiple returns occur from
+@code{map}, the values returned by earlier returns are not mutated.
@lisp
(map cadr '((a b) (d e) (g h))) @result{} (b e h)
@@ -79,18 +80,17 @@ the values returned by earlier returns are not mutated.
@deffn procedure string-map proc @vari{string} @varii{string}@dots{}
-It is an error if @var{proc} does not
-accept as many arguments as there are @var{string}s
-and return a single character.
+It is an error if @var{proc} does not accept as many arguments as
+there are @var{string}s and return a single character.
-The @code{string-map} procedure applies @var{proc} element-wise to the elements of the
-@var{string}s and returns a string of the results, in order.
-If more than one @var{string} is given and not all strings have the same length,
-@code{string-map} terminates when the shortest string runs out.
-The dynamic order in which @var{proc} is applied to the elements of the
-@var{string}s is unspecified.
-If multiple returns occur from @code{string-map},
-the values returned by earlier returns are not mutated.
+The @code{string-map} procedure applies @var{proc} element-wise to
+the elements of the @var{string}s and returns a string of the results,
+in order. If more than one @var{string} is given and not all strings
+have the same length, @code{string-map} terminates when the shortest
+string runs out. The dynamic order in which @var{proc} is applied
+to the elements of the @var{string}s is unspecified. If multiple
+returns occur from @code{string-map}, the values returned by earlier
+returns are not mutated.
@lisp
(string-map char-foldcase "AbdEgH") @result{} "abdegh"
@@ -114,18 +114,17 @@ the values returned by earlier returns are not mutated.
@deffn procedure vector-map proc @vari{vector} @varii{vector}@dots{}
-It is an error if @var{proc} does not
-accept as many arguments as there are @var{vector}s
-and return a single value.
+It is an error if @var{proc} does not accept as many arguments as
+there are @var{vector}s and return a single value.
-The @code{vector-map} procedure applies @var{proc} element-wise to the elements of the
-@var{vector}s and returns a vector of the results, in order.
-If more than one @var{vector} is given and not all vectors have the same length,
-@code{vector-map} terminates when the shortest vector runs out.
-The dynamic order in which @var{proc} is applied to the elements of the
-@var{vector}s is unspecified.
-If multiple returns occur from @code{vector-map},
-the values returned by earlier returns are not mutated.
+The @code{vector-map} procedure applies @var{proc} element-wise to
+the elements of the @var{vector}s and returns a vector of the results,
+in order. If more than one @var{vector} is given and not all vectors
+have the same length, @code{vector-map} terminates when the shortest
+vector runs out. The dynamic order in which @var{proc} is applied
+to the elements of the @var{vector}s is unspecified. If multiple
+returns occur from @code{vector-map}, the values returned by earlier
+returns are not mutated.
@lisp
(vector-map cadr '#((a b) (d e) (g h))) @result{} #(b e h)
@@ -149,17 +148,18 @@ the values returned by earlier returns are not mutated.
@deffn procedure for-each proc @vari{list} @varii{list}@dots{}
-It is an error if @var{proc} does not
-accept as many arguments as there are @var{list}s.
+It is an error if @var{proc} does not accept as many arguments as
+there are @var{list}s.
-The arguments to @code{for-each} are like the arguments to @code{map}, but
-@code{for-each} calls @var{proc} for its side effects rather than for its
-values. Unlike @code{map}, @code{for-each} is guaranteed to call @var{proc} on
-the elements of the @var{list}s in order from the first element(s) to the
-last, and the value returned by @code{for-each} is unspecified.
-If more than one @var{list} is given and not all lists have the same length,
-@code{for-each} terminates when the shortest list runs out.
-The @var{list}s can be circular, but it is an error if all of them are circular.
+The arguments to @code{for-each} are like the arguments to @code{map},
+but @code{for-each} calls @var{proc} for its side effects rather than
+for its values. Unlike @code{map}, @code{for-each} is guaranteed
+to call @var{proc} on the elements of the @var{list}s in order
+from the first element(s) to the last, and the value returned by
+@code{for-each} is unspecified. If more than one @var{list} is given
+and not all lists have the same length, @code{for-each} terminates
+when the shortest list runs out. The @var{list}s can be circular,
+but it is an error if all of them are circular.
It is an error for @var{proc} to mutate any of the lists.
@@ -175,18 +175,18 @@ It is an error for @var{proc} to mutate any of the lists.
@deffn procedure string-for-each proc string1 string2@dots{}
-It is an error if @var{proc} does not
-accept as many arguments as there are @var{string}s.
+It is an error if @var{proc} does not accept as many arguments as
+there are @var{string}s.
The arguments to @code{string-for-each} are like the arguments to
-@code{string-map}, but @code{string-for-each} calls @var{proc} for its side
-effects rather than for its values. Unlike @code{string-map},
-@code{string-for-each} is guaranteed to call @var{proc} on the elements of
-the @var{list}s in order from the first element(s) to the last, and the
-value returned by @code{string-for-each} is unspecified.
-If more than one @var{string} is given and not all strings have the same length,
-@code{string-for-each} terminates when the shortest string runs out.
-It is an error for @var{proc} to mutate any of the strings.
+@code{string-map}, but @code{string-for-each} calls @var{proc} for its
+side effects rather than for its values. Unlike @code{string-map},
+@code{string-for-each} is guaranteed to call @var{proc} on the elements
+of the @var{list}s in order from the first element(s) to the last,
+and the value returned by @code{string-for-each} is unspecified.
+If more than one @var{string} is given and not all strings have the
+same length, @code{string-for-each} terminates when the shortest string
+runs out. It is an error for @var{proc} to mutate any of the strings.
@lisp
(let ((v '()))
@@ -201,18 +201,18 @@ It is an error for @var{proc} to mutate any of the strings.
@deffn procedure vector-for-each proc @vari{vector} @varii{vector}@dots{}
-It is an error if @var{proc} does not
-accept as many arguments as there are @var{vector}s.
+It is an error if @var{proc} does not accept as many arguments as
+there are @var{vector}s.
The arguments to @code{vector-for-each} are like the arguments to
-@code{vector-map}, but @code{vector-for-each} calls @var{proc} for its side
-effects rather than for its values. Unlike @code{vector-map},
-@code{vector-for-each} is guaranteed to call @var{proc} on the elements of
-the @var{vector}s in order from the first element(s) to the last, and
-the value returned by @code{vector-for-each} is unspecified.
-If more than one @var{vector} is given and not all vectors have the same length,
-@code{vector-for-each} terminates when the shortest vector runs out.
-It is an error for @var{proc} to mutate any of the vectors.
+@code{vector-map}, but @code{vector-for-each} calls @var{proc} for its
+side effects rather than for its values. Unlike @code{vector-map},
+@code{vector-for-each} is guaranteed to call @var{proc} on the elements
+of the @var{vector}s in order from the first element(s) to the last,
+and the value returned by @code{vector-for-each} is unspecified.
+If more than one @var{vector} is given and not all vectors have the
+same length, @code{vector-for-each} terminates when the shortest vector
+runs out. It is an error for @var{proc} to mutate any of the vectors.
@lisp
(let ((v (make-list 5)))
@@ -231,45 +231,44 @@ It is an error for @var{proc} to mutate any of the vectors.
It is an error if @var{proc} does not accept one
argument.
-The procedure @code{call-with-current-continuation} (or its
-equivalent abbreviation @code{call/cc}) packages
-the current continuation (see the rationale below) as an ``escape
-procedure'' and passes it as an argument to
-@var{proc}.
-The escape procedure is a Scheme procedure that, if it is
-later called, will abandon whatever continuation is in effect at that later
-time and will instead use the continuation that was in effect
-when the escape procedure was created. Calling the escape procedure
-will cause the invocation of @var{before} and @var{after} thunks installed using
-@code{dynamic-wind}.
-
-The escape procedure accepts the same number of arguments as the continuation to
-the original call to @code{call-with-current-continuation}.
-Most continuations take only one value.
-Continuations created by the @code{call-with-values}
+The procedure @code{call-with-current-continuation} (or its equivalent
+abbreviation @code{call/cc}) packages the current continuation (see
+the rationale below) as an ``escape procedure'' and passes it as an
+argument to @var{proc}. The escape procedure is a Scheme procedure
+that, if it is later called, will abandon whatever continuation is in
+effect at that later time and will instead use the continuation that
+was in effect when the escape procedure was created. Calling the
+escape procedure will cause the invocation of @var{before} and
+@var{after} thunks installed using @code{dynamic-wind}.
+
+The escape procedure accepts the same number of
+arguments as the continuation to the original call to
+@code{call-with-current-continuation}. Most continuations take only
+one value. Continuations created by the @code{call-with-values}
procedure (including the initialization expressions of
-@code{define-values}, @code{let-values}, and @code{let*-values} expressions),
-take the number of values that the consumer expects.
+@code{define-values}, @code{let-values}, and @code{let*-values}
+expressions), take the number of values that the consumer expects.
The continuations of all non-final expressions within a sequence
-of expressions, such as in @code{lambda}, @code{case-lambda}, @code{begin},
-@code{let}, @code{let*}, @code{letrec}, @code{letrec*}, @code{let-values},
-@code{let*-values}, @code{let-syntax}, @code{letrec-syntax}, @code{parameterize},
-@code{guard}, @code{case}, @code{cond}, @code{when}, and @code{unless} expressions,
-take an arbitrary number of values because they discard the values passed
-to them in any event.
-The effect of passing no values or more than one value to continuations
-that were not created in one of these ways is unspecified.
-
-The escape procedure that is passed to @var{proc} has
-unlimited extent just like any other procedure in Scheme. It can be stored
-in variables or data structures and can be called as many times as desired.
-However, like the @code{raise} and @code{error} procedures, it never
-returns to its caller.
+of expressions, such as in @code{lambda}, @code{case-lambda},
+@code{begin}, @code{let}, @code{let*}, @code{letrec}, @code{letrec*},
+@code{let-values}, @code{let*-values}, @code{let-syntax},
+@code{letrec-syntax}, @code{parameterize}, @code{guard}, @code{case},
+@code{cond}, @code{when}, and @code{unless} expressions, take an
+arbitrary number of values because they discard the values passed to
+them in any event. The effect of passing no values or more than one
+value to continuations that were not created in one of these ways
+is unspecified.
+
+The escape procedure that is passed to @var{proc} has unlimited
+extent just like any other procedure in Scheme. It can be stored
+in variables or data structures and can be called as many times as
+desired. However, like the @code{raise} and @code{error} procedures,
+it never returns to its caller.
The following examples show only the simplest ways in which
-@code{call-with-current-continuation} is used. If all real uses were as
-simple as these examples, there would be no need for a procedure with
-the power of @code{call-with-current-continuation}.
+@code{call-with-current-continuation} is used. If all real uses were
+as simple as these examples, there would be no need for a procedure
+with the power of @code{call-with-current-continuation}.
@lisp
(call-with-current-continuation
@@ -301,34 +300,33 @@ the power of @code{call-with-current-continuation}.
@subheading Rationale:
A common use of @code{call-with-current-continuation} is for
-structured, non-local exits from loops or procedure bodies, but in fact
-@code{call-with-current-continuation} is useful for implementing a
-wide variety of advanced control structures.
-In fact, @code{raise} and @code{guard} provide a more structured mechanism
-for non-local exits.
-
-Whenever a Scheme expression is evaluated there is a
-@dfn{continuation} wanting the result of the expression. The continuation
-represents an entire (default) future for the computation. If the expression is
-evaluated at the REPL, for example, then the continuation might take the
-result, print it on the screen, prompt for the next input, evaluate it, and
-so on forever. Most of the time the continuation includes actions
-specified by user code, as in a continuation that will take the result,
-multiply it by the value stored in a local variable, add seven, and give
-the answer to the REPL's continuation to be printed. Normally these
-ubiquitous continuations are hidden behind the scenes and programmers do not
-think much about them. On rare occasions, however, a programmer
-needs to deal with continuations explicitly.
-The @code{call-with-current-continuation} procedure allows Scheme programmers to do
-that by creating a procedure that acts just like the current
-continuation.
+structured, non-local exits from loops or procedure bodies, but in
+fact @code{call-with-current-continuation} is useful for implementing a
+wide variety of advanced control structures. In fact, @code{raise} and
+@code{guard} provide a more structured mechanism for non-local exits.
+
+Whenever a Scheme expression is evaluated there is a @dfn{continuation}
+wanting the result of the expression. The continuation represents
+an entire (default) future for the computation. If the expression is
+evaluated at the REPL, for example, then the continuation might take
+the result, print it on the screen, prompt for the next input, evaluate
+it, and so on forever. Most of the time the continuation includes
+actions specified by user code, as in a continuation that will take
+the result, multiply it by the value stored in a local variable, add
+seven, and give the answer to the REPL's continuation to be printed.
+Normally these ubiquitous continuations are hidden behind the scenes
+and programmers do not think much about them. On rare occasions,
+however, a programmer needs to deal with continuations explicitly.
+The @code{call-with-current-continuation} procedure allows Scheme
+programmers to do that by creating a procedure that acts just like
+the current continuation.
@end deffn
@deffn procedure values obj@dots{}
-Delivers all of its arguments to its continuation. The @code{values} procedure might be defined
-as follows:
+Delivers all of its arguments to its continuation. The @code{values}
+procedure might be defined as follows:
@lisp
(define (values . things)
@@ -340,11 +338,11 @@ as follows:
@deffn procedure call-with-values producer consumer
-Calls its @var{producer} argument with no arguments and
-a continuation that, when passed some values, calls the
-@var{consumer} procedure with those values as arguments.
-The continuation for the call to @var{consumer} is the
-continuation of the call to @code{call-with-values}.
+Calls its @var{producer} argument with no arguments and a continuation
+that, when passed some values, calls the @var{consumer} procedure with
+those values as arguments. The continuation for the call to
+@var{consumer} is the continuation of the call to
+@code{call-with-values}.
@lisp
(call-with-values (lambda () (values 4 5))
@@ -357,20 +355,19 @@ continuation of the call to @code{call-with-values}.
@deffn procedure dynamic-wind before thunk after
-Calls @var{thunk} without arguments, returning the result(s) of this call.
-@var{Before} and @var{after} are called, also without arguments, as required
-by the following rules. Note that, in the absence of calls to continuations
-captured using @code{call-with-current-continuation}, the three arguments are
-called once each, in order. @var{Before} is called whenever execution
-enters the dynamic extent of the call to @var{thunk} and @var{after} is called
-whenever it exits that dynamic extent. The dynamic extent of a procedure
-call is the period between when the call is initiated and when it
-returns.
+Calls @var{thunk} without arguments, returning the result(s) of this
+call. @var{Before} and @var{after} are called, also without arguments,
+as required by the following rules. Note that, in the absence of calls
+to continuations captured using @code{call-with-current-continuation},
+the three arguments are called once each, in order. @var{Before}
+is called whenever execution enters the dynamic extent of the
+call to @var{thunk} and @var{after} is called whenever it exits
+that dynamic extent. The dynamic extent of a procedure call is
+the period between when the call is initiated and when it returns.
The @var{before} and @var{after} thunks are called in the same dynamic
-environment as the call to @code{dynamic-wind}.
-In Scheme, because of @code{call-with-current-continuation}, the
-dynamic extent of a call is not always a single, connected time period.
-It is defined as follows:
+environment as the call to @code{dynamic-wind}. In Scheme, because of
+@code{call-with-current-continuation}, the dynamic extent of a call is
+not always a single, connected time period. It is defined as follows:
@itemize @bullet
@@ -381,35 +378,39 @@ called procedure begins.
@item
The dynamic extent is also entered when execution is not within
the dynamic extent and a continuation is invoked that was captured
-(using @code{call-with-current-continuation}) during the dynamic extent.
+(using @code{call-with-current-continuation}) during the dynamic
+extent.
@item
It is exited when the called procedure returns.
@item
-It is also exited when execution is within the dynamic extent and
-a continuation is invoked that was captured while not within the
-dynamic extent.
-@end itemize
-
-If a second call to @code{dynamic-wind} occurs within the dynamic extent of the
-call to @var{thunk} and then a continuation is invoked in such a way that the
-@var{after}s from these two invocations of @code{dynamic-wind} are both to be
-called, then the @var{after} associated with the second (inner) call to
-@code{dynamic-wind} is called first.
+It is also exited when execution is within the dynamic extent and a
+continuation is invoked that was captured while not within the dynamic
+extent.
-If a second call to @code{dynamic-wind} occurs within the dynamic extent of the
-call to @var{thunk} and then a continuation is invoked in such a way that the
-@var{before}s from these two invocations of @code{dynamic-wind} are both to be
-called, then the @var{before} associated with the first (outer) call to
-@code{dynamic-wind} is called first.
-
-If invoking a continuation requires calling the @var{before} from one call
-to @code{dynamic-wind} and the @var{after} from another, then the @var{after}
-is called first.
+@end itemize
-The effect of using a captured continuation to enter or exit the dynamic
-extent of a call to @var{before} or @var{after} is unspecified.
+If a second call to @code{dynamic-wind} occurs within the dynamic
+extent of the call to @var{thunk} and then a continuation is invoked
+in such a way that the @var{after}s from these two invocations of
+@code{dynamic-wind} are both to be called, then the @var{after}
+associated with the second (inner) call to @code{dynamic-wind} is
+called first.
+
+If a second call to @code{dynamic-wind} occurs within the dynamic
+extent of the call to @var{thunk} and then a continuation is invoked
+in such a way that the @var{before}s from these two invocations of
+@code{dynamic-wind} are both to be called, then the @var{before}
+associated with the first (outer) call to @code{dynamic-wind} is
+called first.
+
+If invoking a continuation requires calling the @var{before} from
+one call to @code{dynamic-wind} and the @var{after} from another,
+then the @var{after} is called first.
+
+The effect of using a captured continuation to enter or exit the
+dynamic extent of a call to @var{before} or @var{after} is unspecified.
@lisp
(let ((path '())