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 1e0d807a102014be0a621fe6d84dc74925213d58
parent f2937728cc4b938a7ba99da67b0ac336c495363f
Author: Wolfgang Corcoran-Mathe <wcm@sigwinch.xyz>
Date:   Fri,  2 Feb 2024 13:21:35 -0500

Equivalence procs.: Reflow & tidy examples.

Diffstat:
Mdoc/r7rs-small/procedures/equivalence-predicates.texinfo | 273+++++++++++++++++++++++++++++++++++++++++--------------------------------------
1 file changed, 141 insertions(+), 132 deletions(-)

diff --git a/doc/r7rs-small/procedures/equivalence-predicates.texinfo b/doc/r7rs-small/procedures/equivalence-predicates.texinfo @@ -44,22 +44,21 @@ finite composition of Scheme's standard arithmetic procedures, provided it does not result in a NaN value. @item -@var{obj@sub{1}} and -@var{obj@sub{2}} are both characters and are the same character according to the @code{char=?} procedure +@var{obj@sub{1}} and @var{obj@sub{2}} are both characters and are the +same character according to the @code{char=?} procedure (@ref{Characters}). @item -@var{obj@sub{1}} and -@var{obj@sub{2}} are both the empty list. +@var{obj@sub{1}} and @var{obj@sub{2}} are both the empty list. @item -@var{obj@sub{1}} and -@var{obj@sub{2}} are pairs, vectors, bytevectors, records, or strings that denote the same location in -the store (@ref{Storage model}). +@var{obj@sub{1}} and @var{obj@sub{2}} are pairs, vectors, bytevectors, +records, or strings that denote the same location in the store +(@ref{Storage model}). @item -@var{obj@sub{1}} and -@var{obj@sub{2}} are procedures whose location tags are equal (@ref{Procedures}). +@var{obj@sub{1}} and @var{obj@sub{2}} are procedures whose location +tags are equal (@ref{Procedures}). @end itemize @@ -68,221 +67,231 @@ The @code{eqv?} procedure returns @code{#f} if: @itemize @item -@var{obj@sub{1}} and -@var{obj@sub{2}} are of different types (@ref{Disjointness of types}). +@var{obj@sub{1}} and @var{obj@sub{2}} are of different types +(@ref{Disjointness of types}). @item -one of -@var{obj@sub{1}} and -@var{obj@sub{2}} is @code{#t} but the other is @code{#f}. +one of @var{obj@sub{1}} and @var{obj@sub{2}} is @code{#t} but the other +is @code{#f}. @item -@var{obj@sub{1}} and -@var{obj@sub{2}} are symbols but are not the same symbol according to the @code{symbol=?} procedure -(@ref{Symbols}). +@var{obj@sub{1}} and @var{obj@sub{2}} are symbols but are not the same +symbol according to the @code{symbol=?} procedure (@ref{Symbols}). @item -one of -@var{obj@sub{1}} and -@var{obj@sub{2}} is an exact number but the other is an inexact number. +one of @var{obj@sub{1}} and @var{obj@sub{2}} is an exact number but the +other is an inexact number. @item -@var{obj@sub{1}} and -@var{obj@sub{2}} are both exact numbers and are numerically unequal (in the sense of @code{=}). +@var{obj@sub{1}} and @var{obj@sub{2}} are both exact numbers and are +numerically unequal (in the sense of @code{=}). @item -@var{obj@sub{1}} and -@var{obj@sub{2}} are both inexact numbers such that either they are numerically unequal (in the -sense of @code{=}), or they do not yield the same results (in the sense of @code{eqv?}) when passed as -arguments to any other procedure that can be defined as a finite composition of -Scheme's standard arithmetic procedures, provided it does not result in a NaN value. As -an exception, the behavior of @code{eqv?} is unspecified when both -@var{obj@sub{1}} and +@var{obj@sub{1}} and @var{obj@sub{2}} are both inexact numbers such +that either they are numerically unequal (in the sense of @code{=}), or +they do not yield the same results (in the sense of @code{eqv?}) when +passed as arguments to any other procedure that can be defined as a +finite composition of Scheme's standard arithmetic procedures, provided +it does not result in a NaN value. As an exception, the behavior of +@code{eqv?} is unspecified when both @var{obj@sub{1}} and @var{obj@sub{2}} are NaN. @item -@var{obj@sub{1}} and -@var{obj@sub{2}} are characters for which the @code{char=?} procedure returns @code{#f}. +@var{obj@sub{1}} and @var{obj@sub{2}} are characters for which the +@code{char=?} procedure returns @code{#f}. @item -one of -@var{obj@sub{1}} and -@var{obj@sub{2}} is the empty list but the other is not. +one of @var{obj@sub{1}} and @var{obj@sub{2}} is the empty list but the +other is not. @item -@var{obj@sub{1}} and -@var{obj@sub{2}} are pairs, vectors, bytevectors, records, or strings that denote distinct locations. +@var{obj@sub{1}} and @var{obj@sub{2}} are pairs, vectors, bytevectors, +records, or strings that denote distinct locations. @item -@var{obj@sub{1}} and -@var{obj@sub{2}} are procedures that would behave differently (return different values or have -different side effects) for some arguments. +@var{obj@sub{1}} and @var{obj@sub{2}} are procedures that would behave +differently (return different values or have different side effects) +for some arguments. @end itemize @example -(eqv? 'a 'a) @result{} #t -(eqv? 'a 'b) @result{} #f -(eqv? 2 2) @result{} #t -(eqv? 2 2.0) @result{} #f -(eqv? '() '()) @result{} #t -(eqv? 100000000 100000000) @result{} #t -(eqv? 0.0 +nan.0) @result{} #f -(eqv? (cons 1 2) (cons 1 2)) @result{} #f +(eqv? 'a 'a) @result{} #t +(eqv? 'a 'b) @result{} #f +(eqv? 2 2) @result{} #t +(eqv? 2 2.0) @result{} #f +(eqv? '() '()) @result{} #t +(eqv? 100000000 100000000) @result{} #t +(eqv? 0.0 +nan.0) @result{} #f +(eqv? (cons 1 2) (cons 1 2)) @result{} #f (eqv? (lambda () 1) - (lambda () 2)) @result{} #f + (lambda () 2)) @result{} #f (let ((p (lambda (x) x))) - (eqv? p p)) @result{} #t -(eqv? #f 'nil) @result{} #f + (eqv? p p)) @result{} #t +(eqv? #f 'nil) @result{} #f @end example -The following examples illustrate cases in which the above rules -do not fully specify the behavior of @code{eqv?}. All that can be said about such cases is that the -value returned by @code{eqv?} must be a boolean. +The following examples illustrate cases in which the above rules do not +fully specify the behavior of @code{eqv?}. All that can be said about +such cases is that the value returned by @code{eqv?} must be a boolean. @example -(eqv? "" "") @result{} @r{unspecified} -(eqv? '#() '#()) @result{} @r{unspecified} +(eqv? "" "") @result{} @r{unspecified} +(eqv? '#() '#()) @result{} @r{unspecified} (eqv? (lambda (x) x) - (lambda (x) x)) @result{} @r{unspecified} + (lambda (x) x)) @result{} @r{unspecified} (eqv? (lambda (x) x) - (lambda (y) y)) @result{} @r{unspecified} -(eqv? 1.0e0 1.0f0) @result{} @r{unspecified} -(eqv? +nan.0 +nan.0) @result{} @r{unspecified} + (lambda (y) y)) @result{} @r{unspecified} +(eqv? 1.0e0 1.0f0) @result{} @r{unspecified} +(eqv? +nan.0 +nan.0) @result{} @r{unspecified} @end example Note that @code{(eqv? 0.0 -0.0)} will return @code{#f} if negative zero is distinguished, and @code{#t} if negative zero is not distinguished. -The next set of examples shows the use of @code{eqv?} with procedures that have local state. The -@code{gen-counter} procedure must return a distinct procedure every time, since each -procedure has its own internal counter. The @code{gen-loser} procedure, however, returns -operationally equivalent procedures each time, since the local state does not affect the -value or side effects of the procedures. However, @code{eqv?} may or may not detect this -equivalence. +The next set of examples shows the use of @code{eqv?} with procedures +that have local state. The @code{gen-counter} procedure must return a +distinct procedure every time, since each procedure has its own +internal counter. The @code{gen-loser} procedure, however, returns +operationally equivalent procedures each time, since the local state +does not affect the value or side effects of the procedures. However, +@code{eqv?} may or may not detect this equivalence. @example (define gen-counter (lambda () (let ((n 0)) (lambda () (set! n (+ n 1)) n)))) + (let ((g (gen-counter))) - (eqv? g g)) @result{} #t + (eqv? g g)) @result{} #t + (eqv? (gen-counter) (gen-counter)) - @result{} #f + @result{} #f (define gen-loser (lambda () (let ((n 0)) (lambda () (set! n (+ n 1)) 27)))) + (let ((g (gen-loser))) - (eqv? g g)) @result{} #t + (eqv? g g)) @result{} #t + (eqv? (gen-loser) (gen-loser)) - @result{} @r{unspecified} + @result{} @r{unspecified} (letrec ((f (lambda () (if (eqv? f g) 'both 'f))) (g (lambda () (if (eqv? f g) 'both 'g)))) (eqv? f g)) - @result{} @r{unspecified} + @result{} @r{unspecified} (letrec ((f (lambda () (if (eqv? f g) 'f 'both))) (g (lambda () (if (eqv? f g) 'g 'both)))) (eqv? f g)) - @result{} #f + @result{} #f @end example -Since it is an error to modify constant objects (those returned by literal -expressions), implementations may share structure between constants where -appropriate. Thus the value of @code{eqv?} on constants is sometimes -implementation-dependent. +Since it is an error to modify constant objects (those returned by +literal expressions), implementations may share structure between +constants where appropriate. Thus the value of @code{eqv?} on constants +is sometimes implementation-dependent. @example -(eqv? '(a) '(a)) @result{} @r{unspecified} -(eqv? "a" "a") @result{} @r{unspecified} -(eqv? '(b) (cdr '(a b))) @result{} @r{unspecified} +(eqv? '(a) '(a)) @result{} @r{unspecified} +(eqv? "a" "a") @result{} @r{unspecified} +(eqv? '(b) (cdr '(a b))) @result{} @r{unspecified} (let ((x '(a))) - (eqv? x x)) @result{} #t + (eqv? x x)) @result{} #t @end example The above definition of @code{eqv?} allows implementations latitude in -their treatment of procedures and literals: implementations may either detect or fail to -detect that two procedures or two literals are equivalent to each other, and can decide -whether or not to merge representations of equivalent objects by using the same pointer -or bit pattern to represent both. +their treatment of procedures and literals: implementations may either +detect or fail to detect that two procedures or two literals are +equivalent to each other, and can decide whether or not to merge +representations of equivalent objects by using the same pointer or bit +pattern to represent both. -Note: If inexact numbers are represented as IEEE binary floating-point numbers, then -an implementation of @code{eqv?} that simply compares equal-sized inexact numbers for -bitwise equality is correct by the above definition. +Note: If inexact numbers are represented as IEEE binary floating-point +numbers, then an implementation of @code{eqv?} that simply compares +equal-sized inexact numbers for bitwise equality is correct by the +above definition. @end deffn @deffn procedure eq? @var{obj@sub{1}} @var{obj@sub{2}} -The @code{eq?} procedure is similar to @code{eqv?} except that in some cases it is -capable of discerning distinctions finer than those detectable by -@code{eqv?}. It must always return @code{#f} when @code{eqv?} also -would, but may return @code{#f} in some cases where @code{eqv?} would return @code{#t}. - -On symbols, booleans, the empty list, pairs, and records, -and also on non-empty -strings, vectors, and bytevectors, @code{eq?} and @code{eqv?} are guaranteed to have the same -behavior. On procedures, @code{eq?} must return true if the arguments' location -tags are equal. On numbers and characters, @code{eq?}'s behavior is -implementation-dependent, but it will always return either true or -false. On empty strings, empty vectors, and empty bytevectors, @code{eq?} may also behave -differently from @code{eqv?}. +The @code{eq?} procedure is similar to @code{eqv?} except that in some +cases it is capable of discerning distinctions finer than those +detectable by @code{eqv?}. It must always return @code{#f} when +@code{eqv?} also would, but may return @code{#f} in some cases where +@code{eqv?} would return @code{#t}. + +On symbols, booleans, the empty list, pairs, and records, and also on +non-empty strings, vectors, and bytevectors, @code{eq?} and @code{eqv?} +are guaranteed to have the same behavior. On procedures, @code{eq?} +must return true if the arguments' location tags are equal. On numbers +and characters, @code{eq?}'s behavior is implementation-dependent, but +it will always return either true or false. On empty strings, empty +vectors, and empty bytevectors, @code{eq?} may also behave differently +from @code{eqv?}. @example -(eq? 'a 'a) @result{} #t -(eq? '(a) '(a)) @result{} @r{unspecified} -(eq? (list 'a) (list 'a)) @result{} #f -(eq? "a" "a") @result{} @r{unspecified} -(eq? "" "") @result{} @r{unspecified} -(eq? '() '()) @result{} #t -(eq? 2 2) @result{} @r{unspecified} -(eq? #\A #\A) @result{} @r{unspecified} -(eq? car car) @result{} #t +(eq? 'a 'a) @result{} #t +(eq? '(a) '(a)) @result{} @r{unspecified} +(eq? (list 'a) (list 'a)) @result{} #f +(eq? "a" "a") @result{} @r{unspecified} +(eq? "" "") @result{} @r{unspecified} +(eq? '() '()) @result{} #t +(eq? 2 2) @result{} @r{unspecified} +(eq? #\A #\A) @result{} @r{unspecified} +(eq? car car) @result{} #t (let ((n (+ 2 3))) - (eq? n n)) @result{} @r{unspecified} + (eq? n n)) @result{} @r{unspecified} (let ((x '(a))) - (eq? x x)) @result{} #t + (eq? x x)) @result{} #t (let ((x '#())) - (eq? x x)) @result{} #t + (eq? x x)) @result{} #t (let ((p (lambda (x) x))) - (eq? p p)) @result{} #t + (eq? p p)) @result{} #t @end example -Rationale: It will usually be possible to implement @code{eq?} much more efficiently than -@code{eqv?}, for example, as a simple pointer comparison instead of as some more -complicated operation. One reason is that it is not always possible to compute @code{eqv?} -of two numbers in constant time, whereas @code{eq?} implemented as pointer comparison +Rationale: It will usually be possible to implement @code{eq?} much +more efficiently than @code{eqv?}, for example, as a simple pointer +comparison instead of as some more complicated operation. One reason is +that it is not always possible to compute @code{eqv?} of two numbers in +constant time, whereas @code{eq?} implemented as pointer comparison will always finish in constant time. @end deffn @deffn procedure equal? @var{obj@sub{1}} @var{obj@sub{2}} -The @code{equal?} procedure, when applied to pairs, vectors, strings and bytevectors, recursively -compares them, returning @code{#t} when the unfoldings of its arguments into (possibly infinite) -trees are equal (in the sense of @code{equal?}) as ordered trees, and @code{#f} otherwise. It returns the -same as @code{eqv?} when applied to booleans, symbols, numbers, characters, ports, -procedures, and the empty list. If two objects are @code{eqv?}, they must be @code{equal?} as well. In all -other cases, @code{equal?} may return either @code{#t} or @code{#f}. Even if its arguments are circular data -structures, @code{equal?} must always terminate. +The @code{equal?} procedure, when applied to pairs, vectors, strings +and bytevectors, recursively compares them, returning @code{#t} when +the unfoldings of its arguments into (possibly infinite) trees are +equal (in the sense of @code{equal?}) as ordered trees, and @code{#f} +otherwise. It returns the same as @code{eqv?} when applied to booleans, +symbols, numbers, characters, ports, procedures, and the empty list. If +two objects are @code{eqv?}, they must be @code{equal?} as well. In all +other cases, @code{equal?} may return either @code{#t} or @code{#f}. +Even if its arguments are circular data structures, @code{equal?} must +always terminate. @example -(equal? 'a 'a) @result{} #t -(equal? '(a) '(a)) @result{} #t +(equal? 'a 'a) @result{} #t +(equal? '(a) '(a)) @result{} #t (equal? '(a (b) c) - '(a (b) c)) @result{} #t -(equal? "abc" "abc") @result{} #t -(equal? 2 2) @result{} #t + '(a (b) c)) @result{} #t +(equal? "abc" "abc") @result{} #t +(equal? 2 2) @result{} #t (equal? (make-vector 5 'a) - (make-vector 5 'a)) @result{} #t + (make-vector 5 'a)) @result{} #t (equal? '#1=(a b . #1#) - '#2=(a b a b . #2#)) @result{} #t + '#2=(a b a b . #2#)) @result{} #t (equal? (lambda (x) x) - (lambda (y) y)) @result{} @r{unspecified} + (lambda (y) y)) @result{} @r{unspecified} @end example -Note: A rule of thumb is that objects are generally @code{equal?} if they print the same. +Note: A rule of thumb is that objects are generally @code{equal?} if +they print the same. + @end deffn