commit 98f7a00517fdd061bcca375c062e5523e84572c5
parent ab8e87625ad6f290f00d425b50e3d0e529b7724a
Author: Wolfgang Corcoran-Mathe <wcm@sigwinch.xyz>
Date: Sun, 4 Feb 2024 21:35:08 -0500
Control features: Texify
Diffstat:
1 file changed, 210 insertions(+), 249 deletions(-)
diff --git a/doc/r7rs-small/procedures/control-features.texinfo b/doc/r7rs-small/procedures/control-features.texinfo
@@ -4,13 +4,12 @@
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
-procedure? predicate is also described here.
+@code{procedure?} predicate is also described here.
@deffn procedure procedure? obj
-Returns #t if
-
-obj is a procedure, otherwise returns #f.
+Returns @code{#t} if
+@var{obj} is a procedure, otherwise returns @code{#f}.
@lisp
(procedure? car) @result{} #t
@@ -22,13 +21,13 @@ obj is a procedure, otherwise returns #f.
(call-with-current-continuation procedure?)
@result{} #t
@end lisp
-@end deffn
-@deffn procedure apply proc arg1@dots{} args
+@end deffn
-The apply procedure calls
+@deffn procedure apply proc @vari{arg}@dots{} args
-proc with the elements of the list @code{(append (list arg1 @dots{}) 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
@@ -40,31 +39,24 @@ proc with the elements of the list @code{(append (list arg1 @dots{}) args)} as t
((compose sqrt *) 12 75) @result{} 30
@end lisp
-@end deffn
-
-@deffn procedure map proc list1 list2@dots{}
-
-It is an error if
-
-proc does not accept as many arguments as there are lists and return a single value.
-
-The map procedure applies
-
-proc element-wise to the elements of the
-
-lists and returns a list of the results, in order. If more than one
-
-list is given and not all lists have the same length, map terminates when the shortest list
-runs out. The
-lists can be circular, but it is an error if all of them are circular. It is an error for
+@end deffn
-proc to mutate any of the lists. The dynamic order in which
+@deffn procedure map proc @vari{list} @varii{list}@dots{}
-proc is applied to the elements of the
+It is an error if @var{proc} does not
+accept as many arguments as there are @var{list}s
+and return a single value.
-lists is unspecified. If multiple returns occur from 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)))
@@ -84,28 +76,23 @@ returns are not mutated.
or (2 1)
@end lisp
-@end deffn
-
-@deffn procedure string-map proc string1 string2@dots{}
-
-It is an error if
-
-proc does not accept as many arguments as there are strings and return a single
-character.
-
-The string-map procedure applies
-proc element-wise to the elements of the
-
-strings and returns a string of the results, in order. If more than one
+@end deffn
-string is given and not all strings have the same length, string-map terminates when the
-shortest string runs out. The dynamic order in which
+@deffn procedure string-map proc @vari{string} @varii{string}@dots{}
-proc is applied to the elements of the
+It is an error if @var{proc} does not
+accept as many arguments as there are @var{string}s
+and return a single character.
-strings is unspecified. If multiple returns occur from 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")
@@ -125,27 +112,23 @@ earlier returns are not mutated.
"ululululul")
@result{} "StUdLyCaPs"
@end lisp
-@end deffn
-
-@deffn procedure vector-map proc vector1 vector2@dots{}
-
-It is an error if
-proc does not accept as many arguments as there are vectors and return a single value.
-
-The vector-map procedure applies
-
-proc element-wise to the elements of the
-
-vectors and returns a vector of the results, in order. If more than one
+@end deffn
-vector is given and not all vectors have the same length, vector-map terminates when the
-shortest vector runs out. The dynamic order in which
+@deffn procedure vector-map proc @vari{vector} @varii{vector}@dots{}
-proc is applied to the elements of the
+It is an error if @var{proc} does not
+accept as many arguments as there are @var{vector}s
+and return a single value.
-vectors is unspecified. If multiple returns occur from 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)))
@@ -167,32 +150,24 @@ earlier returns are not mutated.
or #(2 1)
@end lisp
-@end deffn
-
-@deffn procedure for-each proc list1 list2@dots{}
-
-It is an error if
-
-proc does not accept as many arguments as there are lists.
-
-The arguments to for-each are like the arguments to map, but for-each calls
-
-proc for its side effects rather than for its values. Unlike map, for-each is guaranteed to
-call
-
-proc on the elements of the
-lists in order from the first element(s) to the last, and the value returned by for-each is
-unspecified. If more than one
+@end deffn
-list is given and not all lists have the same length, for-each terminates when the shortest
-list runs out. The
+@deffn procedure for-each proc @vari{list} @varii{list}@dots{}
-lists can be circular, but it is an error if all of them are circular.
+It is an error if @var{proc} does not
+accept as many arguments as there are @var{list}s.
-It is an error for
+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.
-proc to mutate any of the lists.
+It is an error for @var{proc} to mutate any of the lists.
@lisp
(let ((v (make-vector 5)))
@@ -205,25 +180,18 @@ proc to mutate any of the lists.
@deffn procedure string-for-each proc string1 string2@dots{}
-It is an error if
-
-proc does not accept as many arguments as there are strings.
-
-The arguments to string-for-each are like the arguments to string-map, but
-string-for-each calls
-
-proc for its side effects rather than for its values. Unlike string-map, string-for-each is
-guaranteed to call
-
-proc on the elements of the
+It is an error if @var{proc} does not
+accept as many arguments as there are @var{string}s.
-strings in order from the first element(s) to the last, and the value returned by
-string-for-each is unspecified. If more than one
-
-string is given and not all strings have the same length, string-for-each terminates when
-the shortest string runs out. It is an error for
-
-proc to mutate any of the strings.
+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.
@lisp
(let ((v '()))
@@ -232,29 +200,23 @@ proc to mutate any of the strings.
"abcde")
v) @result{} (101 100 99 98 97)
@end lisp
-@end deffn
-
-@deffn procedure vector-for-each proc vector1 vector2@dots{}
-
-It is an error if
-proc does not accept as many arguments as there are vectors.
-
-The arguments to vector-for-each are like the arguments to vector-map, but
-vector-for-each calls
-
-proc for its side effects rather than for its values. Unlike vector-map, vector-for-each is
-guaranteed to call
-
-proc on the elements of the
+@end deffn
-vectors in order from the first element(s) to the last, and the value returned by
-vector-for-each is unspecified. If more than one
+@deffn procedure vector-for-each proc @vari{vector} @varii{vector}@dots{}
-vector is given and not all vectors have the same length, vector-for-each terminates when
-the shortest vector runs out. It is an error for
+It is an error if @var{proc} does not
+accept as many arguments as there are @var{vector}s.
-proc to mutate any of the vectors.
+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.
@lisp
(let ((v (make-list 5)))
@@ -263,49 +225,54 @@ proc to mutate any of the vectors.
'#(0 1 2 3 4))
v) @result{} (0 1 4 9 16)
@end lisp
+
@end deffn
@deffn procedure call-with-current-continuation proc
@deffnx procedure call/cc proc
-It is an error if
-
-proc does not accept one argument.
-
-The procedure call-with-current-continuation (or its equivalent abbreviation call/cc)
-packages the current continuation (see the rationale below) as an ``escape
-procedure''and passes it as an argument to
-
-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
-
-before and
-
-after thunks installed using dynamic-wind.
+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 call-with-current-continuation. Most continuations take only one
-value. Continuations created by the call-with-values procedure (including the initialization
-expressions of define-values, let-values, and 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 lambda, case-lambda, begin, let, let*, letrec,
-letrec*, let-values, let*-values, let-syntax, letrec-syntax, parameterize, guard, case, cond,
-when, and 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
-
-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 raise and error procedures, it never returns to its caller.
+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.
+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.
The following examples show only the simplest ways in which
-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
-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
@@ -333,29 +300,36 @@ call-with-current-continuation.
(list-length '(a b . c)) @result{} #f
@end lisp
-Rationale: A common use of call-with-current-continuation is for structured,
- non-local exits from loops or procedure bodies, but in fact
- call-with-current-continuation is useful for implementing a wide variety of advanced
- control structures. In fact, raise and guard provide a more structured mechanism
- for non-local exits.
-
- Whenever a Scheme expression is evaluated there is a 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
- call-with-current-continuation procedure allows Scheme programmers to do that
- by creating a procedure that acts just like the 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.
+
@end deffn
-@deffn procedure values obj @dots{}
+@deffn procedure values obj@dots{}
-Delivers all of its arguments to its continuation. The values procedure might be defined
+Delivers all of its arguments to its continuation. The @code{values} procedure might be defined
as follows:
@lisp
@@ -363,18 +337,16 @@ as follows:
(call-with-current-continuation
(lambda (cont) (apply cont things))))
@end lisp
+
@end deffn
@deffn procedure call-with-values producer consumer
-Calls its
-
-producer argument with no arguments and a continuation that, when passed some
-values, calls the
-
-consumer procedure with those values as arguments. The continuation for the call to
-
-consumer is the continuation of the call to 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))
@@ -387,71 +359,59 @@ consumer is the continuation of the call to call-with-values.
@deffn procedure dynamic-wind before thunk after
-Calls
-
-thunk without arguments, returning the result(s) of this call.
-
-Before and
-
-after are called, also without arguments, as required by the following rules. Note that, in
-the absence of calls to continuations captured using call-with-current-continuation, the
-three arguments are called once each, in order.
-
-Before is called whenever execution enters the dynamic extent of the call to
-
-thunk and
-
-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
-
-before and
-
-after thunks are called in the same dynamic environment as the call to dynamic-wind. In
-Scheme, because of call-with-current-continuation, the dynamic extent of a call is not
-always a single, connected time period. It is defined as follows:
-
-* The dynamic extent is entered when execution of the body of the called procedure
- begins.
-
-* The dynamic extent is also entered when execution is not within the dynamic extent
- and a continuation is invoked that was captured (using call-with-current-continuation)
- during the dynamic extent.
-
-* It is exited when the called procedure returns.
-
-* 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 dynamic-wind occurs within the dynamic extent of the call to
-
-thunk and then a continuation is invoked in such a way that the
-
-afters from these two invocations of dynamic-wind are both to be called, then the
-
-after associated with the second (inner) call to dynamic-wind is called first.
-
-If a second call to dynamic-wind occurs within the dynamic extent of the call to
-
-thunk and then a continuation is invoked in such a way that the
-
-befores from these two invocations of dynamic-wind are both to be called, then the
-
-before associated with the first (outer) call to dynamic-wind is called first.
-
-If invoking a continuation requires calling the
-
-before from one call to dynamic-wind and the
-
-after from another, then the
-
-after is called first.
-
-The effect of using a captured continuation to enter or exit the dynamic extent of a call
-to
-
-before or
-
-after is unspecified.
+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:
+
+@itemize @bullet
+
+@item
+The dynamic extent is entered when execution of the body of the
+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.
+
+@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.
+
+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 '())
@@ -473,4 +433,5 @@ after is unspecified.
@result{} (connect talk1 disconnect
connect talk2 disconnect)
@end lisp
+
@end deffn