r7rs-small-texinfo

Unnamed repository; edit this file 'description' to name the repository.
git clone https://kaka.farm/~git/r7rs-small-texinfo
Log | Files | Refs

commit 86aaa15c49769f2edbf1fdf1ad9f22573cec2f88
parent ea7a15fba27ea3604d8c52e570bea78b976761c2
Author: Wolfgang Corcoran-Mathe <wcm@sigwinch.xyz>
Date:   Thu,  1 Feb 2024 00:07:20 -0500

Delayed evaluation: Texify.

Diffstat:
Mdoc/r7rs-small/r7rs-small.texinfo | 136++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 79 insertions(+), 57 deletions(-)

diff --git a/doc/r7rs-small/r7rs-small.texinfo b/doc/r7rs-small/r7rs-small.texinfo @@ -2081,40 +2081,48 @@ invoking the procedure named by @svar{variable}. @node Delayed evaluation @subsection Delayed evaluation -lazy library syntax: (delay @svar{expression}) - -Semantics: The delay construct is used together with the procedure force to implement -lazy evaluation or call by need. (delay @svar{expression}) returns an object called a promise which -at some point in the future can be asked (by the force procedure) to evaluate -@svar{expression}, and deliver the resulting value. The effect of @svar{expression} returning -multiple values is unspecified. - -lazy library syntax: (delay-force @svar{expression}) - -Semantics: The expression (delay-force - -expression) is conceptually similar to (delay (force +@deffn {lazy library syntax} delay @svar{expression} + +The @code{delay} construct is used together with the procedure @code{force} to +implement @dfn{lazy evaluation} or @dfn{call by need}. +@code{(delay} @svar{expression}@code{)} returns an object called a +@dfn{promise} which at some point in the future can be asked (by +the @code{force} procedure) to evaluate +@svar{expression}, and deliver the resulting value. +The effect of @svar{expression} returning multiple values +is unspecified. -expression)), with the difference that forcing the result of delay-force will in effect result in -a tail call to (force +@end deffn -expression), while forcing the result of (delay (force +@deffn {lazy library syntax} delay-force @svar{expression} -expression)) might not. Thus iterative lazy algorithms that might result in a long series of -chains of delay and force can be rewritten using delay-force to prevent consuming +The expression @code{(delay-force} @var{expression}@code{)} is conceptually similar to +@code{(delay (force} @var{expression}@code{))}, +with the difference that forcing the result +of @code{delay-force} will in effect result in a tail call to +@code{(force} @var{expression}@code{)}, +while forcing the result of +@code{(delay (force} @var{expression}@code{))} +might not. Thus +iterative lazy algorithms that might result in a long series of chains of +@code{delay} and @code{force} +can be rewritten using @code{delay-force} to prevent consuming unbounded space during evaluation. -@deffn {lazy library procedure} force promise - -The force procedure forces the value of a +@end deffn -promise created by delay, delay-force, or make-promise.If no value has been computed for -the promise, then a value is computed and returned. The value of the promise must be -cached (or ``memoized'') so that if it is forced a second time, the previously computed -value is returned. Consequently, a delayed expression is evaluated using the parameter -values and exception handler of the call to force which first requested its value. If +@deffn {lazy library procedure} force promise -promise is not a promise, it may be returned unchanged. +The @code{force} procedure forces the value of a @var{promise} created +by @code{delay}, @code{delay-force}, or @code{make-promise}. +If no value has been computed for the promise, then a value is +computed and returned. The value of the promise must be cached (or +``memoized'') so that if it is forced a second time, the previously +computed value is returned. +Consequently, a delayed expression is evaluated using the parameter +values and exception handler of the call to @code{force} which first +requested its value. +If @var{promise} is not a promise, it may be returned unchanged. @example (force (delay (+ 1 2))) @result{} 3 @@ -2136,12 +2144,16 @@ promise is not a promise, it may be returned unchanged. @result{} 2 @end example +@end deffn + The following example is a mechanical transformation of a lazy -stream-filtering algorithm into Scheme. Each call to a constructor is wrapped in delay, and -each argument passed to a deconstructor is wrapped in force. The use of (delay-force ...) -instead of (delay (force ...)) around the body of the procedure ensures that an -ever-growing sequence of pending promises does not exhaust available storage, because -force will in effect force such sequences iteratively. +stream-filtering algorithm into Scheme. Each call to a constructor is +wrapped in @code{delay}, and each argument passed to a deconstructor is +wrapped in @code{force}. The use of @code{(delay-force @dots{})} instead of +@code{(delay (force @dots{}))} around the body of the procedure ensures that an +ever-growing sequence of pending promises does not +exhaust available storage, +because @code{force} will in effect force such sequences iteratively. @example (define (stream-filter p? s) @@ -2154,14 +2166,14 @@ force will in effect force such sequences iteratively. (delay (cons h (stream-filter p? t))) (stream-filter p? t)))))) -(head (tail (tail (stream-filter odd? integers)))) - @result{} 5 +(head (tail (tail (stream-filter odd? integers)))) @result{} 5 @end example -The following examples are not intended to illustrate good -programming style, as delay, force, and delay-force are mainly intended for programs -written in the functional style. However, they do illustrate the property that only one value -is computed for a promise, no matter how many times it is forced. +The following examples are not intended to illustrate good programming +style, as @code{delay}, @code{force}, and @code{delay-force} are mainly intended +for programs written in the functional style. +However, they do illustrate the property that only one value is +computed for a promise, no matter how many times it is forced. @example (define count 0) @@ -2171,39 +2183,49 @@ is computed for a promise, no matter how many times it is forced. count (force p))))) (define x 5) -p @result{} a promise -(force p) @result{} 6 -p @result{} a promise, still +p @result{} @r{a promise} +(force p) @result{} 6 +p @result{} @r{a promise, still} (begin (set! x 10) - (force p)) @result{} 6 + (force p)) @result{} 6 @end example -Various extensions to this semantics of delay, force and delay-force -are supported in some implementations: +Various extensions to this semantics of @code{delay}, @code{force} and +@code{delay-force} are supported in some implementations: -* Calling force on an object that is not a promise may simply return the object. +@itemize +@item +Calling @code{force} on an object that is not a promise may simply return the object. -* It may be the case that there is no means by which a promise can be operationally +@item +It may be the case that there is no means by which a promise can be operationally distinguished from its forced value. That is, expressions like the following may evaluate - to either #t or to #f, depending on the implementation: + to either @code{#t} or to @code{#f}, depending on the implementation: + +@example +(eqv? (delay 1) 1) @result{} @r{unspecified} +(pair? (delay (cons 1 2))) @result{} @r{unspecified} +@end example - (eqv? (delay 1) 1) @result{} unspecified - (pair? (delay (cons 1 2))) @result{} unspecified -* Implementations may implement ``implicit forcing,'' where the value of a promise is - forced by procedures that operate only on arguments of a certain type, like cdr and *. - However, procedures that operate uniformly on their arguments, like list, must not +@item +Implementations may implement ``implicit forcing,'' where the value of a promise is + forced by procedures that operate only on arguments of a certain type, like +@code{cdr} and @code{*}. + However, procedures that operate uniformly on their arguments, like +@code{list}, must not force them. @example -(+ (delay (* 3 7)) 13) @result{} unspecified - (car - (list (delay (* 3 7)) 13)) @result{} a promise +(+ (delay (* 3 7)) 13) @result{} @r{unspecified} +(car + (list (delay (* 3 7)) 13)) @result{} @r{a promise} @end example -@end deffn +@end itemize @deffn {lazy library procedure} promise? obj -The promise? procedure returns #t if its argument is a promise, and #f otherwise. Note +The promise? procedure returns @code{#t} if its argument is a promise, and +@code{#f} otherwise. Note that promises are not necessarily disjoint from other Scheme types such as procedures. @end deffn