r7rs-small-texinfo

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit d08340b4cdb4ef3aba48b08cd209a8588896e45e
parent f6b9e8cb856eae7cd55efc1f55df1cf5d15a0903
Author: Wolfgang Corcoran-Mathe <wcm@sigwinch.xyz>
Date:   Mon, 29 Jan 2024 13:19:46 -0500

Merge branch 'master' of https://codeberg.org/kakafarm/r7rs-small-texinfo

Diffstat:
Mdoc/r7rs-small/r7rs-small.texinfo | 1530++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 892 insertions(+), 638 deletions(-)

diff --git a/doc/r7rs-small/r7rs-small.texinfo b/doc/r7rs-small/r7rs-small.texinfo @@ -410,11 +410,7 @@ template for a call to the procedure. Argument names in the template are italicized. Thus the header line -procedure: (vector-ref - -vector - -k) +procedure: (vector-ref vector k) indicates that the procedure bound to the vector-ref variable takes two arguments, a @@ -424,16 +420,10 @@ vector and an exact non-negative integer k (see below). The header lines -procedure: (make-vector - -k) - - -procedure: (make-vector +procedure: (make-vector k) -k -fill) +procedure: (make-vector k fill) indicate that the make-vector procedure must be defined to take either one or two @@ -1381,6 +1371,8 @@ If all <test>s evaluate to #f, and there is no else clause, then the result of t expression is unspecified; if there is an else clause, then its <expression>s are evaluated in order, and the values of the last one are returned. +@example + (cond ((> 3 2) 'greater) ((< 3 2) 'less)) ⟹ greater @@ -1391,6 +1383,8 @@ order, and the values of the last one are returned. (cond ((assv 'b '((a 1) (b 2))) => cadr) (else #f)) ⟹ 2 +@end example + syntax: (case <key> <clause1> <clause2> …) Syntax: <Key> can be any expression. Each <clause> has the form @@ -1417,6 +1411,8 @@ evaluated. It is an error if its value is not a procedure accepting one argument procedure is then called on the value of the <key> and the values returned by this procedure are returned by the case expression. +@example + (case (* 2 3) ((2 3 5 7) 'prime) ((1 4 6 8 9) 'composite)) ⟹ composite @@ -1428,6 +1424,8 @@ procedure are returned by the case expression. ((w y) 'semivowel) (else => (lambda (x) x))) ⟹ c +@end example + syntax: (and <test1> …) Semantics: The <test> expressions are evaluated from left to right, and if any expression @@ -1435,11 +1433,15 @@ evaluates to #f (see section 6.3), then #f is returned. Any remaining expression evaluated. If all the expressions evaluate to true values, the values of the last expression are returned. If there are no expressions, then #t is returned. +@example + (and (= 2 2) (> 2 1)) ⟹ #t (and (= 2 2) (< 2 1)) ⟹ #f (and 1 2 'c '(f g)) ⟹ (f g) (and) ⟹ #t +@end example + syntax: (or <test1> …) Semantics: The <test> expressions are evaluated from left to right, and the value of the @@ -1447,12 +1449,16 @@ first expression that evaluates to a true value (see section 6.3) is returned. A expressions are not evaluated. If all expressions evaluate to #f or if there are no expressions, then #f is returned. +@example + (or (= 2 2) (> 2 1)) ⟹ #t (or (= 2 2) (< 2 1)) ⟹ #t (or #f #f #f) ⟹ #f (or (memq 'b '(a b c)) (/ 3 0)) ⟹ (b c) +@end example + syntax: (when <test> <expression1> <expression2> …) Syntax: The <test> is an expression. @@ -1460,11 +1466,15 @@ Syntax: The <test> is an expression. Semantics: The test is evaluated, and if it evaluates to a true value, the expressions are evaluated in order. The result of the when expression is unspecified. +@example + (when (= 1 1.0) (display "1") (display "2")) ⟹ unspecified and prints 12 +@end example + syntax: (unless <test> <expression1> <expression2> …) Syntax: The <test> is an expression. @@ -1472,11 +1482,15 @@ Syntax: The <test> is an expression. Semantics: The test is evaluated, and if it evaluates to #f, the expressions are evaluated in order. The result of the unless expression is unspecified. +@example + (unless (= 1 1.0) (display "1") (display "2")) ⟹ unspecified and prints nothing +@end example + syntax: (cond-expand <ce-clause1> <ce-clause2> …) Syntax: The cond-expand expression type provides a way to statically expand different @@ -1544,6 +1558,8 @@ order), the <variable>s are bound to fresh locations holding the results, the <b evaluated in the extended environment, and the values of the last expression of <body> are returned. Each binding of a <variable> has <body> as its region. +@example + (let ((x 2) (y 3)) (* x y)) ⟹ 6 @@ -1552,6 +1568,8 @@ are returned. Each binding of a <variable> has <body> as its region. (z (+ x y))) (* z x))) ⟹ 35 See also “named let,” section 4.2.4. +@end example + syntax: (let* <bindings> <body>) Syntax: <Bindings> has the form @@ -1565,11 +1583,15 @@ is that part of the let* expression to the right of the binding. Thus the second done in an environment in which the first binding is visible, and so on. The <variable>s need not be distinct. +@example + (let ((x 2) (y 3)) (let* ((x 7) (z (+ x y))) (* z x))) ⟹ 70 +@end example + syntax: (letrec <bindings> <body>) Syntax: <Bindings> has the form @@ -1585,6 +1607,8 @@ the resulting environment, and the values of the last expression in <body> are r Each binding of a <variable> has the entire letrec expression as its region, making it possible to define mutually recursive procedures. +@example + (letrec ((even? (lambda (n) (if (zero? n) @@ -1596,7 +1620,11 @@ possible to define mutually recursive procedures. #f (even? (- n 1)))))) (even? 88)) -⟹ #t One restriction on letrec is very important: if it is not possible to evaluate each <init> +⟹ #t + +@end example + +One restriction on letrec is very important: if it is not possible to evaluate each <init> without assigning or referring to the value of any <variable>, it is an error. The restriction is necessary because letrec is defined in terms of a procedure call where a lambda expression binds the <variable>s to the values of the <init>s. In the most common uses of @@ -1622,6 +1650,8 @@ the corresponding <variable> or the <variable> of any of the bindings that follo <bindings>, it is an error. Another restriction is that it is an error to invoke the continuation of an <init> more than once. +@example + ;; Returns the arithmetic, geometric, and ;; harmonic means of a nested list of numbers (define (means ton) @@ -1641,6 +1671,9 @@ continuation of an <init> more than once. (values (mean values values) (mean exp log) (mean / /)))) + +@end example + Evaluating (means '(3 (1 4))) returns three values: 8/3, 2.28942848510666 (approximately), and 36/19. @@ -1663,9 +1696,13 @@ are returned. Each binding of a <variable> has <body> as its region. It is an error if the <formals> do not match the number of values returned by the corresponding <init>. +@example + (let-values (((root rem) (exact-integer-sqrt 32))) (* root rem)) ⟹ 35 +@end example + syntax: (let*-values <mv binding spec> <body>) Syntax: <Mv binding spec> has the form @@ -1680,11 +1717,15 @@ each <formals> including the <init>s to its right as well as <body>. Thus the se is evaluated in an environment in which the first set of bindings is visible and initialized, and so on. +@example + (let ((a 'a) (b 'b) (x 'x) (y 'y)) (let*-values (((a b) (values x y)) ((x y) (values a b))) (list a b x y))) ⟹ (x y x y) +@end example + @node Sequencing @subsection Sequencing @@ -1709,6 +1750,8 @@ evaluated sequentially from left to right, and the values of the last <expressio returned. This expression type is used to sequence side effects such as assignments or input and output. +@example + (define x 0) (and (= x 0) @@ -1716,8 +1759,9 @@ input and output. (+ x 1))) ⟹ 6 (begin (display "4 plus 1 equals ") - (display (+ 4 1))) ⟹ unspecified - and prints 4 plus 1 equals 5 + (display (+ 4 1))) ⟹ unspecified and prints 4 plus 1 equals 5 + +@end example Note that there is a third form of begin used as a library declaration: see section 5.6.1. @@ -1758,6 +1802,8 @@ variables. A <step> can be omitted, in which case the effect is the same as if (<variable> <init> <variable>) had been written instead of (<variable> <init>). +@example + (do ((vec (make-vector 5)) (i 0 (+ i 1))) ((= i 5) vec) @@ -1768,6 +1814,8 @@ A <step> can be omitted, in which case the effect is the same as if (<variable> (sum 0 (+ sum (car x)))) ((null? x) sum))) ⟹ 25 +@end example + syntax: (let <variable> <bindings> <body>) Semantics: “Named let” is a variant on the syntax of let which provides a more general @@ -1777,6 +1825,8 @@ procedure whose formal arguments are the bound variables and whose body is <body Thus the execution of <body> can be repeated by invoking the procedure named by <variable>. +@example + (let loop ((numbers '(3 -2 1 6 -5)) (nonneg '()) (neg '())) @@ -1791,6 +1841,8 @@ Thus the execution of <body> can be repeated by invoking the procedure named by (cons (car numbers) neg))))) ⟹ ((6 1 3) (-5 -2)) +@end example + @node Delayed evaluation @subsection Delayed evaluation @@ -1829,6 +1881,8 @@ values and exception handler of the call to force which first requested its valu promise is not a promise, it may be returned unchanged. +@example + (force (delay (+ 1 2))) ⟹ 3 (let ((p (delay (+ 1 2)))) (list (force p) (force p))) @@ -1845,13 +1899,19 @@ promise is not a promise, it may be returned unchanged. (lambda (stream) (cdr (force stream)))) (head (tail (tail integers))) - ⟹ 2 The following example is a mechanical transformation of a lazy + ⟹ 2 + +@end example + +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. +@example + (define (stream-filter p? s) (delay-force (if (null? (force s)) @@ -1863,11 +1923,17 @@ force will in effect force such sequences iteratively. (stream-filter p? t)))))) (head (tail (tail (stream-filter odd? integers)))) - ⟹ 5 The following examples are not intended to illustrate good + ⟹ 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. +@example + (define count 0) (define p (delay (begin (set! count (+ count 1)) @@ -1879,7 +1945,11 @@ p ⟹ a promise (force p) ⟹ 6 p ⟹ a promise, still (begin (set! x 10) - (force p)) ⟹ 6 Various extensions to this semantics of delay, force and delay-force + (force p)) ⟹ 6 + +@end example + +Various extensions to this semantics of delay, force and delay-force are supported in some implementations: * Calling force on an object that is not a promise may simply return the object. @@ -1895,21 +1965,21 @@ are supported in some implementations: However, procedures that operate uniformly on their arguments, like list, must not force them. - (+ (delay (* 3 7)) 13) ⟹ unspecified +@example + +(+ (delay (* 3 7)) 13) ⟹ unspecified (car (list (delay (* 3 7)) 13)) ⟹ a promise -lazy library procedure: (promise? +@end example -obj) +lazy library procedure: (promise? obj) The promise? procedure returns #t if its argument is a promise, and #f otherwise. Note that promises are not necessarily disjoint from other Scheme types such as procedures. -lazy library procedure: (make-promise - -obj) +lazy library procedure: (make-promise obj) The make-promise procedure returns a promise which, when forced, will return @@ -1978,6 +2048,8 @@ thread and threads created inside <body>. Parameter objects can be used to specify configurable settings for a computation without the need to pass the value to every procedure in the call chain explicitly. +@example + (define radix (make-parameter 10 @@ -1998,6 +2070,8 @@ without the need to pass the value to every procedure in the call chain explicit (parameterize ((radix 0)) (f 12)) ⟹ error +@end example + @node Exception handling @subsection Exception handling @@ -2018,6 +2092,8 @@ of the guard expression. See section 6.11 for a more complete discussion of exceptions. +@example + (guard (condition ((assq 'a condition) => cdr) ((assq 'b condition))) @@ -2030,6 +2106,8 @@ See section 6.11 for a more complete discussion of exceptions. (raise (list (cons 'b 23)))) ⟹ (b . 23) +@end example + @node Quasiquotation @subsection Quasiquotation @@ -2057,6 +2135,7 @@ or vector <qq template>. comma at-sign sequence. @example + `(list ,(+ 1 2) 4) ⟹ (list 3 4) (let ((name 'a)) `(list ,name ',name)) ⟹ (list a (quote a)) @@ -2069,6 +2148,7 @@ or vector <qq template>. (let ((foo '(foo bar)) (@@baz 'baz)) `(list ,@@foo , @@baz)) ⟹ (list foo bar baz) + @end example Quasiquote expressions can be nested. Substitutions are made only @@ -2076,36 +2156,56 @@ for unquoted components appearing at the same nesting level as the outermost quasiquote. The nesting level increases by one inside each successive quasiquotation, and decreases by one inside each unquotation. +@example + `(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f) ⟹ (a `(b ,(+ 1 2) ,(foo 4 d) e) f) (let ((name1 'x) (name2 'y)) `(a `(b ,,name1 ,',name2 d) e)) -⟹ (a `(b ,x ,'y d) e) A quasiquote expression may return either newly allocated, mutable +⟹ (a `(b ,x ,'y d) e) + +@end example + +A quasiquote expression may return either newly allocated, mutable objects or literal structure for any structure that is constructed at run time during the evaluation of the expression. Portions that do not need to be rebuilt are always literal. -Thus, - -(let ((a 3)) `((1 2) ,a ,4 ,'five 6)) may be treated as equivalent to either of the following +Thus, @code{(let ((a 3)) `((1 2) ,a ,4 ,'five 6))} may be treated as equivalent to either of the following expressions: +@example + `((1 2) 3 4 five 6) (let ((a 3)) (cons '(1 2) - (cons a (cons 4 (cons 'five '(6)))))) However, it is not equivalent to this expression: + (cons a (cons 4 (cons 'five '(6)))))) + +@end example + +However, it is not equivalent to this expression: -(let ((a 3)) (list (list 1 2) a 4 'five 6)) The two notations `<qq template> and (quasiquote <qq +@example + +(let ((a 3)) (list (list 1 2) a 4 'five 6)) + +@end example + +The two notations `<qq template> and (quasiquote <qq template>) are identical in all respects. ,<expression> is identical to (unquote <expression>), and ,@@<expression> is identical to (unquote-splicing <expression>). The write procedure may output either format. +@example + (quasiquote (list (unquote (+ 1 2)) 4)) ⟹ (list 3 4) '(quasiquote (list (unquote (+ 1 2)) 4)) ⟹ `(list ,(+ 1 2) 4) i.e., (quasiquote (list (unquote (+ 1 2)) 4)) +@end example + It is an error if any of the identifiers quasiquote, unquote, or unquote-splicing appear in positions within a <qq template> otherwise than as described above. @@ -2128,6 +2228,8 @@ results of the procedure call. It is an error for the arguments not to agree with the <formals> of any <clause>. +@example + (define range (case-lambda ((e) (range 0 e)) @@ -2138,6 +2240,8 @@ It is an error for the arguments not to agree with the <formals> of any <clause> (range 3) ⟹ (0 1 2) (range 3 5) ⟹ (3 4) +@end example + @node Macros @section Macros @@ -2206,6 +2310,8 @@ the syntactic environment of the let-syntax expression with macros whose keyword the <keyword>s, bound to the specified transformers. Each binding of a <keyword> has <body> as its region. +@example + (let-syntax ((given-that (syntax-rules () ((given-that test stmt1 stmt2 ...) (if test @@ -2220,6 +2326,8 @@ the <keyword>s, bound to the specified transformers. Each binding of a <keyword> (let ((x 'inner)) (m)))) ⟹ outer +@end example + syntax: (letrec-syntax <bindings> <body>) Syntax: Same as for let-syntax. @@ -2231,6 +2339,8 @@ has the <transformer spec>s as well as the <body> within its region, so the tran can transcribe expressions into uses of the macros introduced by the letrec-syntax expression. +@example + (letrec-syntax ((my-or (syntax-rules () ((my-or) #f) @@ -2250,6 +2360,8 @@ expression. (if y) y))) ⟹ 7 +@end example + @node Pattern language @subsection Pattern language @@ -2370,6 +2482,8 @@ within <template> are treated as ordinary identifiers. In particular, the templa (<ellipsis> <ellipsis>) produces a single <ellipsis>. This allows syntactic abstractions to expand into code containing ellipses. +@example + (define-syntax be-like-begin (syntax-rules () ((be-like-begin name) @@ -2379,20 +2493,43 @@ expand into code containing ellipses. (begin expr (... ...)))))))) (be-like-begin sequence) -(sequence 1 2 3 4) ⟹ 4 As an example, if let and cond are defined as in section 7.3 then +(sequence 1 2 3 4) ⟹ 4 + +@end example + +As an example, if let and cond are defined as in section 7.3 then they are hygienic (as required) and the following is not an error. +@example + (let ((=> #f)) - (cond (#t => 'ok))) ⟹ ok The macro transformer for cond recognizes => as a local -variable, and hence an expression, and not as the base identifier =>, which the macro -transformer treats as a syntactic keyword. Thus the example expands into + (cond (#t => 'ok))) ⟹ ok + +@end example + +The macro transformer for cond recognizes @code{=>} as a local +variable, and hence an expression, and not as the base identifier +@code{=>}, which the macro transformer treats as a syntactic +keyword. Thus the example expands into + +@example (let ((=> #f)) - (if #t (begin => 'ok))) instead of + (if #t (begin => 'ok))) + +@end example + +instead of + +@example (let ((=> #f)) (let ((temp #t)) - (if temp ('ok temp)))) which would result in an invalid procedure call. + (if temp ('ok temp)))) + +@end example + +which would result in an invalid procedure call. @node Signaling errors in macro transformers @subsection Signaling errors in macro transformers @@ -2407,6 +2544,8 @@ invalid use of the macro, which can provide more descriptive error messages. information. Applications cannot count on being able to catch syntax errors with exception handlers or guards. +@example + (define-syntax simple-let (syntax-rules () ((_ (head ... ((x . y) val) . tail) @@ -2418,6 +2557,8 @@ exception handlers or guards. ((lambda (name ...) body1 body2 ...) val ...)))) +@end example + @node Program structure @chapter Program structure @@ -2521,15 +2662,25 @@ them. The simplest kind of variable definition takes one of the following forms: more variables followed by a space-delimited period and another variable (as in a lambda expression). This form is equivalent to - (define <variable> +@example + +(define <variable> (lambda (<formals>) <body>)). + +@end example + + * (define (<variable> . <formal>) <body>) <Formal> is a single variable. This form is equivalent to - (define <variable> +@example + +(define <variable> (lambda <formal> <body>)). +@end example + @menu * Top level definitions:: * Internal definitions:: @@ -2547,12 +2698,16 @@ However, if <variable> is not bound, or is a syntactic keyword, then the definit <variable> to a new location before performing the assignment, whereas it would be an error to perform a set! on an unboundvariable. +@example + (define add3 (lambda (x) (+ x 3))) (add3 3) ⟹ 6 (define first car) (first '(1 2)) ⟹ 1 +@end example + @node Internal definitions @subsection Internal definitions @@ -2564,17 +2719,29 @@ definitions described above. The variables defined by internal definitions are l <body>. That is, <variable> is bound rather than assigned, and the region of the binding is the entire <body>. For example, +@example + (let ((x 5)) (define foo (lambda (y) (bar x y))) (define bar (lambda (a b) (+ (* a b) a))) - (foo (+ x 3))) ⟹ 45 An expanded <body> containing internal definitions can always + (foo (+ x 3))) ⟹ 45 + +@end example + +An expanded <body> containing internal definitions can always be converted into a completely equivalent letrec* expression. For example, the let expression in the above example is equivalent to +@example + (let ((x 5)) (letrec* ((foo (lambda (y) (bar x y))) (bar (lambda (a b) (+ (* a b) a)))) - (foo (+ x 3)))) Just as for the equivalent letrec* expression, it is an error if it is not + (foo (+ x 3)))) + +@end example + +Just as for the equivalent letrec* expression, it is an error if it is not possible to evaluate each <expression> of every internal definition in a <body> without assigning or referring to the value of the corresponding <variable> or the <variable> of any of the definitions that follow it in <body>. @@ -2599,6 +2766,8 @@ Semantics: <Expression> is evaluated, and the <formals> are bound to the return the same way that the <formals> in a lambda expression are matched to the arguments in a procedure call. +@example + (define-values (x y) (exact-integer-sqrt 17)) (list x y) ⟹ (4 1) @@ -2606,6 +2775,8 @@ a procedure call. (define-values (x y) (values 1 2)) (+ x y)) ⟹ 3 +@end example + @node Syntax definitions @section Syntax definitions @@ -2624,6 +2795,8 @@ internal syntax definition, and is local to the <body> in which it is defined. A syntax keyword before its corresponding definition is an error. In particular, a use that precedes an inner definition will not apply an outer definition. +@example + (let ((x 1) (y 2)) (define-syntax swap! (syntax-rules () @@ -2634,6 +2807,8 @@ precedes an inner definition will not apply an outer definition. (swap! x y) (list x y)) ⟹ (2 1) +@end example + Macros can expand into definitions in any context that permits them. However, it is an error for a definition to define an identifier whose binding has to be known in order to determine the meaning of the definition itself, or of any preceding definition that belongs @@ -2642,6 +2817,8 @@ to define an identifier whose binding has to be known in order to determine the boundary between the internal definitions and the expressions of the body it belongs to. For example, the following are errors: +@example + (define define 3) (begin (define begin list)) @@ -2657,6 +2834,8 @@ For example, the following are errors: (define foo x) (plus foo x))) +@end example + @node Record-type definitions @section Record-type definitions @@ -2708,14 +2887,21 @@ An instance of define-record-type is equivalent to the following definitions: For instance, the following record-type definition +@example + (define-record-type <pare> (kons x y) pare? (x kar set-kar!) (y kdr)) + +@end example + defines kons to be a constructor, kar and kdr to be accessors, set-kar! to be a modifier, and pare? to be a predicate for instances of <pare>. +@example + (pare? (kons 1 2)) ⟹ #t (pare? (cons 1 2)) ⟹ #f (kar (kons 1 2)) ⟹ 1 @@ -2724,6 +2910,8 @@ and pare? to be a predicate for instances of <pare>. (set-kar! k 3) (kar k)) ⟹ 3 +@end example + @node Libraries @section Libraries @@ -2828,6 +3016,8 @@ The following example shows how a program can be divided into libraries plus a r small main program [16]. If the main program is entered into a REPL, it is not necessary to import the base library. +@example + (define-library (example grid) (export make rows cols ref each (rename put! set!)) @@ -2883,10 +3073,10 @@ import the base library. (define (life-print grid) (display "\x1B;[1H\x1B;[J") ; clear vt100 (each grid - (lambda (i j v) - (display (if v "*" " ")) - (when (= j (- (cols grid) 1)) - (newline))))) + (lambda (i j v) + (display (if v "*" " ")) + (when (= j (- (cols grid) 1)) + (newline))))) (define (life grid iterations) (do ((i 0 (+ i 1)) (grid0 grid grid1) @@ -2894,9 +3084,9 @@ import the base library. grid0)) ((= i iterations)) (each grid0 - (lambda (j k v) - (let ((a (life-alive? grid0 j k))) - (set! grid1 j k a)))) + (lambda (j k v) + (let ((a (life-alive? grid0 j k))) + (set! grid1 j k a)))) (life-print grid1))))) ;; Main program. @@ -2916,6 +3106,8 @@ import the base library. ;; Run for 80 iterations. (life grid 80) +@end example + @node The REPL @section The REPL @@ -2982,19 +3174,12 @@ symmetric, reflexive, and transitive. Of the equivalence predicates described in section, eq? is the finest or most discriminating, equal? is the coarsest, and eqv? is slightly less discriminating than eq?. -procedure: (eqv? - -obj1 - -obj2) - +procedure: (eqv? obj1 obj2) The eqv? procedure defines a useful equivalence relation on objects. Briefly, it returns #t if -obj1 and - -obj2 are normally regarded as the same object. This relation is left slightly open to +obj1 and obj2 are normally regarded as the same object. This relation is left slightly open to interpretation, but the following partial specification of eqv? holds for all implementations of Scheme. @@ -3096,6 +3281,8 @@ The eqv? procedure returns #f if: obj2 are procedures that would behave differently (return different values or have different side effects) for some arguments. +@example + (eqv? 'a 'a) ⟹ #t (eqv? 'a 'b) ⟹ #f (eqv? 2 2) ⟹ #t @@ -3108,10 +3295,16 @@ The eqv? procedure returns #f if: (lambda () 2)) ⟹ #f (let ((p (lambda (x) x))) (eqv? p p)) ⟹ #t -(eqv? #f 'nil) ⟹ #f The following examples illustrate cases in which the above rules +(eqv? #f 'nil) ⟹ #f + +@end example + +The following examples illustrate cases in which the above rules do not fully specify the behavior of eqv?. All that can be said about such cases is that the value returned by eqv? must be a boolean. +@example + (eqv? "" "") ⟹ unspecified (eqv? '#() '#()) ⟹ unspecified (eqv? (lambda (x) x) @@ -3119,7 +3312,11 @@ value returned by eqv? must be a boolean. (eqv? (lambda (x) x) (lambda (y) y)) ⟹ unspecified (eqv? 1.0e0 1.0f0) ⟹ unspecified -(eqv? +nan.0 +nan.0) ⟹ unspecified Note that (eqv? 0.0 -0.0) will return #f if negative zero +(eqv? +nan.0 +nan.0) ⟹ unspecified + +@end example + +Note that (eqv? 0.0 -0.0) will return #f if negative zero is distinguished, and #t if negative zero is not distinguished. The next set of examples shows the use of eqv? with procedures that have local state. The @@ -3129,6 +3326,8 @@ operationally equivalent procedures each time, since the local state does not af value or side effects of the procedures. However, eqv? may or may not detect this equivalence. +@example + (define gen-counter (lambda () (let ((n 0)) @@ -3154,16 +3353,26 @@ equivalence. (letrec ((f (lambda () (if (eqv? f g) 'f 'both))) (g (lambda () (if (eqv? f g) 'g 'both)))) (eqv? f g)) - ⟹ #f Since it is an error to modify constant objects (those returned by literal + ⟹ #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 eqv? on constants is sometimes implementation-dependent. +@example + (eqv? '(a) '(a)) ⟹ unspecified (eqv? "a" "a") ⟹ unspecified (eqv? '(b) (cdr '(a b))) ⟹ unspecified (let ((x '(a))) - (eqv? x x)) ⟹ #t The above definition of eqv? allows implementations latitude in + (eqv? x x)) ⟹ #t + +@end example + +The above definition of 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 @@ -3173,11 +3382,7 @@ or bit pattern to represent both. an implementation of eqv? that simply compares equal-sized inexact numbers for bitwise equality is correct by the above definition. -procedure: (eq? - -obj1 - -obj2) +procedure: (eq? obj1 obj2) The eq? procedure is similar to eqv? except that in some cases it is capable of discerning @@ -3191,6 +3396,8 @@ and characters, eq?’s behavior is implementation-dependent, but it will always either true or false. On empty strings, empty vectors, and empty bytevectors, eq? may also behave differently from eqv?. +@example + (eq? 'a 'a) ⟹ #t (eq? '(a) '(a)) ⟹ unspecified (eq? (list 'a) (list 'a)) ⟹ #f @@ -3209,18 +3416,15 @@ behave differently from eqv?. (let ((p (lambda (x) x))) (eq? p p)) ⟹ #t - Rationale: It will usually be possible to implement eq? much more efficiently than +@end example + +Rationale: It will usually be possible to implement eq? much more efficiently than 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 eqv? of two numbers in constant time, whereas eq? implemented as pointer comparison will always finish in constant time. -procedure: (equal? - -obj1 - -obj2) - +procedure: (equal? obj1 obj2) The equal? procedure, when applied to pairs, vectors, strings and bytevectors, recursively compares them, returning #t when the unfoldings of its arguments into (possibly infinite) @@ -3230,6 +3434,8 @@ procedures, and the empty list. If two objects are eqv?, they must be equal? as other cases, equal? may return either #t or #f. Even if its arguments are circular data structures, equal? must always terminate. +@example + (equal? 'a 'a) ⟹ #t (equal? '(a) '(a)) ⟹ #t (equal? '(a (b) c) @@ -3243,7 +3449,9 @@ structures, equal? must always terminate. (equal? (lambda (x) x) (lambda (y) y)) ⟹ unspecified - Note: A rule of thumb is that objects are generally equal? if they print the same. +@end example + +Note: A rule of thumb is that objects are generally equal? if they print the same. @node Numbers @section Numbers @@ -3561,6 +3769,8 @@ x)). The numbers +inf.0, -inf.0, and +nan.0 are real but not rational. +@example + (complex? 3+4i) ⟹ #t (complex? 3) ⟹ #t (real? 3) ⟹ #t @@ -3577,7 +3787,9 @@ The numbers +inf.0, -inf.0, and +nan.0 are real but not rational. (integer? 3.0) ⟹ #t (integer? 8/4) ⟹ #t - Note: The behavior of these type predicates on inexact numbers is unreliable, since +@end example + +Note: The behavior of these type predicates on inexact numbers is unreliable, since any inaccuracy might affect the result. Note: In many implementations the complex? procedure will be the same as @@ -3585,118 +3797,96 @@ The numbers +inf.0, -inf.0, and +nan.0 are real but not rational. exactly or may extend the number system to support some kind of non-complex numbers. -procedure: (exact? +procedure: (exact? z) -z) - -procedure: (inexact? - -z) +procedure: (inexact? z) These numerical predicates provide tests for the exactness of a quantity. For any Scheme number, precisely one of these predicates is true. +@example + (exact? 3.0) ⟹ #f (exact? #e3.0) ⟹ #t (inexact? 3.) ⟹ #t -procedure: (exact-integer? +@end example -z) +procedure: (exact-integer? z) Returns #t if z is both exact and an integer; otherwise returns #f. +@example + (exact-integer? 32) ⟹ #t (exact-integer? 32.0) ⟹ #f (exact-integer? 32/5) ⟹ #f -inexact library procedure: (finite? +@end example -z) +inexact library procedure: (finite? z) The finite? procedure returns #t on all real numbers except +inf.0, -inf.0, and +nan.0, and on complex numbers if their real and imaginary parts are both finite. Otherwise it returns #f. +@example + (finite? 3) ⟹ #t (finite? +inf.0) ⟹ #f (finite? 3.0+inf.0i) ⟹ #f -inexact library procedure: (infinite? +@end example -z) +inexact library procedure: (infinite? z) The infinite? procedure returns #t on the real numbers +inf.0 and -inf.0, and on complex numbers if their real or imaginary parts or both are infinite. Otherwise it returns #f. +@example + (infinite? 3) ⟹ #f (infinite? +inf.0) ⟹ #t (infinite? +nan.0) ⟹ #f (infinite? 3.0+inf.0i) ⟹ #t -inexact library procedure: (nan? +@end example -z) +inexact library procedure: (nan? z) The nan? procedure returns #t on +nan.0, and on complex numbers if their real or imaginary parts or both are +nan.0. Otherwise it returns #f. +@example + (nan? +nan.0) ⟹ #t (nan? 32) ⟹ #f (nan? +nan.0+5.0i) ⟹ #t (nan? 1+2i) ⟹ #f -procedure: (= - -z1 - -z2 - -z3 …) - - -procedure: (< - -x1 - -x2 - -x3 …) - - -procedure: (> - -x1 - -x2 - -x3 …) - +@end example -procedure: (<= +procedure: (= z1 z2 z3 …) -x1 -x2 +procedure: (< x1 x2 x3 …) -x3 …) +procedure: (> x1 x2 x3 …) -procedure: (>= -x1 +procedure: (<= x1 x2 x3 …) -x2 -x3 …) +procedure: (>= x1 x2 x3 …) These procedures return #t if their arguments are (respectively): equal, monotonically @@ -3719,100 +3909,74 @@ These predicates are required to be transitive. results are unreliable because a small inaccuracy can affect the result; this is especially true of = and zero?. When in doubt, consult a numerical analyst. -procedure: (zero? - -z) - - -procedure: (positive? +procedure: (zero? z) -x) +procedure: (positive? x) -procedure: (negative? -x) +procedure: (negative? x) -procedure: (odd? +procedure: (odd? n) -n) - -procedure: (even? - -n) +procedure: (even? n) These numerical predicates test a number for a particular property, returning #t or #f. See note above. -procedure: (max - -x1 - -x2 …) - +procedure: (max x1 x2 …) -procedure: (min -x1 - -x2 …) +procedure: (min x1 x2 …) These procedures return the maximum or minimum of their arguments. +@example + (max 3 4) ⟹ 4 ; exact (max 3.9 4) ⟹ 4.0 ; inexact - Note: If any argument is inexact, then the result will also be inexact (unless the +@end example + +Note: If any argument is inexact, then the result will also be inexact (unless the procedure can prove that the inaccuracy is not large enough to affect the result, which is possible only in unusual implementations). If min or max is used to compare numbers of mixed exactness, and the numerical value of the result cannot be represented as an inexact number without loss of accuracy, then the procedure may report a violation of an implementation restriction. -procedure: (+ +procedure: (+ z1 …) -z1 …) - -procedure: (* - -z1 …) +procedure: (* z1 …) These procedures return the sum or product of their arguments. +@example + (+ 3 4) ⟹ 7 (+ 3) ⟹ 3 (+) ⟹ 0 (* 4) ⟹ 4 (*) ⟹ 1 -procedure: (- - -z) - - -procedure: (- - -z1 - -z2 …) +@end example +procedure: (- z) -procedure: (/ -z) +procedure: (- z1 z2 …) -procedure: (/ +procedure: (/ z) -z1 -z2 …) +procedure: (/ z1 z2 …) With two or more arguments, these procedures return the difference or quotient of their @@ -3823,58 +3987,42 @@ It is an error if any argument of / other than the first is an exact zero. If th argument is an exact zero, an implementation may return an exact zero unless one of the other arguments is a NaN. +@example + (- 3 4) ⟹ -1 (- 3 4 5) ⟹ -6 (- 3) ⟹ -3 (/ 3 4 5) ⟹ 3/20 (/ 3) ⟹ 1/3 +@end example + procedure: (abs x) The abs procedure returns the absolute value of its argument. -(abs -7) ⟹ 7 - -procedure: (floor/ - -n1 - -n2) - - -procedure: (floor-quotient - -n1 - -n2) - - -procedure: (floor-remainder - -n1 +@example -n2) +(abs -7) ⟹ 7 +@end example -procedure: (truncate/ +procedure: (floor/ n1 n2) -n1 -n2) +procedure: (floor-quotient n1 n2) -procedure: (truncate-quotient +procedure: (floor-remainder n1 n2) -n1 -n2) +procedure: (truncate/ n1 n2) -procedure: (truncate-remainder +procedure: (truncate-quotient n1 n2) -n1 -n2) +procedure: (truncate-remainder n1 n2) These procedures implement number-theoretic (integer) division. It is an error if @@ -3973,6 +4121,8 @@ provided all numbers involved in that computation are exact. Examples: +@example + (floor/ 5 2) ⟹ 2 1 (floor/ -5 2) ⟹ -3 1 (floor/ 5 -2) ⟹ -3 -1 @@ -3983,25 +4133,15 @@ Examples: (truncate/ -5 -2) ⟹ 2 -1 (truncate/ -5.0 -2) ⟹ 2.0 -1.0 -procedure: (quotient - -n1 - -n2) - - -procedure: (remainder +@end example -n1 +procedure: (quotient n1 n2) -n2) +procedure: (remainder n1 n2) -procedure: (modulo -n1 - -n2) +procedure: (modulo n1 n2) The quotient and remainder procedures are equivalent to truncate-quotient and @@ -4010,44 +4150,44 @@ truncate-remainder, respectively, and modulo is equivalent to floor-remainder. Note: These procedures are provided for backward compatibility with earlier versions of this report. -procedure: (gcd - -n1 …) +procedure: (gcd n1 …) -procedure: (lcm - -n1 …) +procedure: (lcm n1 …) These procedures return the greatest common divisor or least common multiple of their arguments. The result is always non-negative. +@example + (gcd 32 -36) ⟹ 4 (gcd) ⟹ 0 (lcm 32 -36) ⟹ 288 (lcm 32.0 -36) ⟹ 288.0 ; inexact (lcm) ⟹ 1 -procedure: (numerator - -q) +@end example +procedure: (numerator q) -procedure: (denominator -q) +procedure: (denominator q) These procedures return the numerator or denominator of their argument; the result is computed as if the argument was represented as a fraction in lowest terms. The denominator is always positive. The denominator of 0 is defined to be 1. +@example + (numerator (/ 6 4)) ⟹ 3 (denominator (/ 6 4)) ⟹ 2 (denominator (inexact (/ 6 4))) ⟹ 2.0 +@end example + procedure: (floor x) procedure: (ceiling x) procedure: (truncate x) @@ -4075,6 +4215,8 @@ x is halfway between two integers. be inexact. If an exact value is needed, the result can be passed to the exact procedure. If the argument is infinite or a NaN, then it is returned. +@example + (floor -4.3) ⟹ -5.0 (ceiling -4.3) ⟹ -4.0 (truncate -4.3) ⟹ -4.0 @@ -4088,6 +4230,8 @@ x is halfway between two integers. (round 7/2) ⟹ 4 ; exact (round 7) ⟹ 7 +@end example + procedure: (rationalize x y) The rationalize procedure returns the simplest rational number differing from @@ -4101,62 +4245,42 @@ interval contains a rational number that is simpler than every other rational nu that interval (the simpler 2/5 lies between 2/7 and 3/5). Note that 0 = 0/1 is the simplest rational of all. +@example + (rationalize (exact .3) 1/10) ⟹ 1/3 ; exact (rationalize .3 1/10) ⟹ #i1/3 ; inexact -inexact library procedure: (exp - -z) - - -inexact library procedure: (log - -z) - - -inexact library procedure: (log - -z1 - -z2) - - -inexact library procedure: (sin - -z) +@end example +inexact library procedure: (exp z) -inexact library procedure: (cos -z) +inexact library procedure: (log z) -inexact library procedure: (tan +inexact library procedure: (log z1 z2) -z) +inexact library procedure: (sin z) -inexact library procedure: (asin -z) +inexact library procedure: (cos z) -inexact library procedure: (acos +inexact library procedure: (tan z) -z) +inexact library procedure: (asin z) -inexact library procedure: (atan -z) +inexact library procedure: (acos z) -inexact library procedure: (atan +inexact library procedure: (atan z) -y -x) +inexact library procedure: (atan y x) These procedures compute the usual transcendental functions. The log procedure @@ -4223,25 +4347,19 @@ more detailed discussion of branch cuts, boundary conditions, and implementation these functions. When it is possible, these procedures produce a real result from a real argument. -procedure: (square - -z) - - -Returns the square of +procedure: (square z) -z. This is equivalent to (* -z +Returns the square of z. This is equivalent to @code{(* z z)}. -z). +@example (square 42) ⟹ 1764 (square 2.0) ⟹ 4.0 -inexact library procedure: (sqrt +@end example -z) +inexact library procedure: (sqrt z) Returns the principal square root of @@ -4249,9 +4367,13 @@ Returns the principal square root of z. The result will have either a positive real part, or a zero real part and a non-negative imaginary part. +@example + (sqrt 9) ⟹ 3 (sqrt -1) ⟹ +i +@end example + procedure: (exact-integer-sqrt k) Returns two non-negative exact integers s and r where @@ -4260,14 +4382,14 @@ k = s2 + r and k < (s + 1)2. +@example + (exact-integer-sqrt 4) ⟹ 2 0 (exact-integer-sqrt 5) ⟹ 2 1 -procedure: (expt - -z1 +@end example -z2) +procedure: (expt z1 z2) Returns @@ -4283,38 +4405,22 @@ z1, this is The value of 0z is 1 if (zero? z), 0 if (real-part z) is positive, and an error otherwise. Similarly for 0.0z, with inexact results. -complex library procedure: (make-rectangular +complex library procedure: (make-rectangular x1 x2) -x1 -x2) +complex library procedure: (make-polar x3 x4) -complex library procedure: (make-polar +complex library procedure: (real-part z) -x3 -x4) +complex library procedure: (imag-part z) -complex library procedure: (real-part +complex library procedure: (magnitude z) -z) - -complex library procedure: (imag-part - -z) - - -complex library procedure: (magnitude - -z) - - -complex library procedure: (angle - -z) +complex library procedure: (angle z) Let @@ -4335,38 +4441,16 @@ z be a complex number such that Then all of -(make-rectangular - -x1 - -x2) ⟹ - -z -(make-polar - -x3 - -x4) ⟹ - -z -(real-part - -z) ⟹ - -x1 -(imag-part - -z) ⟹ - -x2 -(magnitude - -z) ⟹ | +@example -x3| -(angle +(make-rectangular x1 x2) ⟹ z +(make-polar x3 x4) ⟹ z +(real-part z) ⟹ x1 +(imag-part z) ⟹ x2 +(magnitude z) ⟹ |x3| +(angle z) ⟹ xangle -z) ⟹ xangle +@end example are true, where −π≤xangle ≤π with xangle = @@ -4380,14 +4464,10 @@ make-rectangular was exact. Rationale: The magnitude procedure is the same as abs for a real argument, but abs is in the base library, whereas magnitude is in the optional complex library. -procedure: (inexact +procedure: (inexact z) -z) - -procedure: (exact - -z) +procedure: (exact z) The procedure inexact returns an inexact representation of @@ -4430,17 +4510,17 @@ radix is not one of 2, 8, 10, or 16. The procedure number->string takes a number and a radix and returns as a string an external representation of the given number in the given radix such that -(let ((number - -number) - (radix +@example -radix)) +(let ((number number) + (radix radix)) (eqv? number (string->number (number->string number radix) radix))) +@end example + is true. It is an error if no possible result makes this expression true. If omitted, radix defaults to 10. @@ -4490,11 +4570,15 @@ signaled due to the content of string. +@example + (string->number "100") ⟹ 100 (string->number "100" 16) ⟹ 256 (string->number "1e2") ⟹ 100.0 - Note: The domain of string->number may be restricted by implementations in the +@end example + +Note: The domain of string->number may be restricted by implementations in the following ways. If all numbers supported by an implementation are real, then string->number is permitted to return #f whenever @@ -4530,16 +4614,22 @@ Scheme values, including #t, count as true. Boolean constants evaluate to themselves, so they do not need to be quoted in programs. +@example + #t ⟹ #t #f ⟹ #f '#f ⟹ #f +@end example + procedure: (not obj) The not procedure returns #t if obj is false, and returns #f otherwise. +@example + (not #t) ⟹ #f (not 3) ⟹ #f (not (list 3)) ⟹ #f @@ -4548,23 +4638,23 @@ obj is false, and returns #f otherwise. (not (list)) ⟹ #f (not 'nil) ⟹ #f +@end example + procedure: (boolean? obj) The boolean? predicate returns #t if obj is either #t or #f and returns #f otherwise. +@example + (boolean? #f) ⟹ #t (boolean? 0) ⟹ #f (boolean? '()) ⟹ #f -procedure: (boolean=? - -boolean1 - -boolean2 +@end example -boolean3 …) +procedure: (boolean=? boolean1 boolean2 boolean3 …) Returns #t if all the arguments are #t or all are #f. @@ -4671,11 +4761,7 @@ obj is a pair, and otherwise returns #f. (pair? '()) ⟹ #f (pair? '#(a b)) ⟹ #f -procedure: (cons - -obj1 - -obj2) +procedure: (cons obj1 obj2) Returns a newly allocated pair whose car is @@ -4740,11 +4826,15 @@ procedure: (cddr pair) These procedures are compositions of car and cdr as follows: +@example + (define (caar x) (car (car x))) (define (cadr x) (car (cdr x))) (define (cdar x) (cdr (car x))) (define (cddr x) (cdr (cdr x))) +@end example + cxr library procedure: (caaar pair) cxr library procedure: (caadr pair) 1 ⋮: 0 ⋮ @@ -4754,7 +4844,13 @@ cxr library procedure: (cddddr pair) These twenty-four procedures are further compositions of car and cdr on the same principles. For example, caddr could be defined by -(define caddr (lambda (x) (car (cdr (cdr x))))). Arbitrary compositions up to four deep are +@example + +(define caddr (lambda (x) (car (cdr (cdr x))))). + +@end example + +Arbitrary compositions up to four deep are provided. procedure: (null? obj) @@ -4770,6 +4866,8 @@ Returns #t if obj is a list. Otherwise, it returns #f. By definition, all lists have finite length and are terminated by the empty list. +@example + (list? '(a b c)) ⟹ #t (list? '()) ⟹ #t (list? '(a . b)) ⟹ #f @@ -4777,6 +4875,8 @@ terminated by the empty list. (set-cdr! x x) (list? x)) ⟹ #f +@end example + procedure: (make-list k) procedure: (make-list k fill) @@ -4786,40 +4886,48 @@ k elements. If a second argument is given, then each element is initialized to fill. Otherwise the initial contents of each element is unspecified. +@example + (make-list 2 3) ⟹ (3 3) -procedure: (list +@end example -obj …) +procedure: (list obj …) Returns a newly allocated list of its arguments. +@example + (list 'a (+ 3 4) 'c) ⟹ (a 7 c) (list) ⟹ () -procedure: (length list) +@end example -Returns the length of +procedure: (length @var{list}) -list. +Returns the length of @var{list}. + +@example (length '(a b c)) ⟹ 3 (length '(a (b) (c d e))) ⟹ 3 (length '()) ⟹ 0 -procedure: (append list …) +@end example -The last argument, if there is one, can be of any type. +procedure: (append @var{list} …) -Returns a list consisting of the elements of the first +The last argument, if there is one, can be of any type. -list followed by the elements of the other +Returns a list consisting of the elements of the first @var{list} +followed by the elements of the other @var{lists}. If there are no +arguments, the empty list is returned. If there is exactly one +argument, it is returned. Otherwise the resulting list is always newly +allocated, except that it shares structure with the last argument. An +improper list results if the last argument is not a proper list. -lists. If there are no arguments, the empty list is returned. If there is exactly one -argument, it is returned. Otherwise the resulting list is always newly allocated, except -that it shares structure with the last argument. An improper list results if the last -argument is not a proper list. +@example (append '(x) '(y)) ⟹ (x y) (append '(a) '(b c d)) ⟹ (a b c d) @@ -4828,19 +4936,22 @@ argument is not a proper list. (append '(a b) '(c . d)) ⟹ (a b c . d) (append '() 'a) ⟹ a -procedure: (reverse list) +@end example + +procedure: (reverse @var{list}) Returns a newly allocated list consisting of the elements of +@var{list} in reverse order. -list in reverse order. +@example (reverse '(a b c)) ⟹ (c b a) (reverse '(a (b c) d (e (f)))) ⟹ ((e (f)) d (b c) a) -procedure: (list-tail list +@end example -k) +procedure: (list-tail list k) It is an error if @@ -4855,15 +4966,17 @@ list obtained by omitting the first k elements. The list-tail procedure could be defined by +@example + (define list-tail (lambda (x k) (if (zero? k) x (list-tail (cdr x) (- k 1))))) -procedure: (list-ref list +@end example -k) +procedure: (list-ref list k) The @@ -4884,11 +4997,15 @@ list k).) +@example + (list-ref '(a b c d) 2) ⟹ c (list-ref '(a b c d) (exact (round 1.8))) ⟹ c +@end example + procedure: (list-set! list k obj) It is an error if @@ -4905,6 +5022,8 @@ k of list. +@example + (let ((ls (list 'one 'two 'five!))) (list-set! ls 2 'three) ls) @@ -4913,6 +5032,8 @@ list. (list-set! '(0 1 2) 1 "oops") ⟹ error ; constant list +@end example + procedure: (memq obj list) procedure: (memv obj list) procedure: (member obj list) @@ -4944,6 +5065,8 @@ list, while memv uses eqv? and member uses compare, if given, and equal? otherwise. +@example + (memq 'a '(a b c)) ⟹ (a b c) (memq 'b '(a b c)) ⟹ (b c) (memq 'a '(b c d)) ⟹ #f @@ -4956,6 +5079,8 @@ compare, if given, and equal? otherwise. (memq 101 '(100 101 102)) ⟹ unspecified (memv 101 '(100 101 102)) ⟹ (101 102) +@end example + procedure: (assq obj alist) procedure: (assv obj alist) procedure: (assoc obj alist) @@ -4982,6 +5107,8 @@ alist, while assv uses eqv? and assoc uses compare if given and equal? otherwise. +@example + (define e '((a 1) (b 2) (c 3))) (assq 'a e) ⟹ (a 1) (assq 'b e) ⟹ (b 2) @@ -4997,7 +5124,9 @@ compare if given and equal? otherwise. (assv 5 '((2 3) (5 7) (11 13))) ⟹ (5 7) - Rationale: Although they are often used as predicates, memq, memv, member, assq, +@end example + +Rationale: Although they are often used as predicates, memq, memv, member, assq, assv, and assoc do not have question marks in their names because they return potentially useful values rather than just #t or #f. @@ -5017,12 +5146,16 @@ obj which is not a list is returned unchanged. It is an error if obj is a circular list. +@example + (define a '(1 8 2 8)) ; a may be immutable (define b (list-copy a)) (set-car! b 3) ; b is mutable b ⟹ (3 8 2 8) a ⟹ (1 8 2 8) +@end example + @node Symbols @section Symbols @@ -5048,6 +5181,8 @@ Returns #t if obj is a symbol, otherwise returns #f. +@example + (symbol? 'foo) ⟹ #t (symbol? (car '(a b))) ⟹ #t (symbol? "bar") ⟹ #f @@ -5055,13 +5190,9 @@ obj is a symbol, otherwise returns #f. (symbol? '()) ⟹ #f (symbol? #f) ⟹ #f -procedure: (symbol=? - -symbol1 - -symbol2 +@end example -symbol3 …) +procedure: (symbol=? symbol1 symbol2 symbol3 …) Returns #t if all the arguments all have the same names in the sense of string=?. @@ -5076,6 +5207,8 @@ Returns the name of symbol as a string, but without adding escapes. It is an error to apply mutation procedures like string-set! to strings returned by this procedure. +@example + (symbol->string 'flying-fish) ⟹ "flying-fish" (symbol->string 'Martin) ⟹ "Martin" @@ -5083,6 +5216,8 @@ procedures like string-set! to strings returned by this procedure. (string->symbol "Malvina")) ⟹ "Malvina" +@end example + procedure: (string->symbol string) Returns the symbol whose name is @@ -5090,6 +5225,8 @@ Returns the symbol whose name is string. This procedure can create symbols with names containing special characters that would require escaping when written, but does not interpret escapes in its input. +@example + (string->symbol "mISSISSIppi") ⟹mISSISSIppi (eqv? 'bitBlt (string->symbol "bitBlt")) @@ -5103,6 +5240,8 @@ would require escaping when written, but does not interpret escapes in its input (string->symbol "K. Harper, M.D."))) ⟹ #t +@end example + @node Characters @section Characters @@ -5181,49 +5320,19 @@ Returns #t if obj is a character, otherwise returns #f. -procedure: (char=? - -char1 - -char2 - -char3 …) - - -procedure: (char<? - -char1 - -char2 - -char3 …) - - -procedure: (char>? +procedure: (char=? char1 char2 char3 …) -char1 -char2 +procedure: (char<? char1 char2 char3 …) -char3 …) +procedure: (char>? char1 char2 char3 …) -procedure: (char<=? -char1 +procedure: (char<=? char1 char2 char3 …) -char2 -char3 …) - - -procedure: (char>=? - -char1 - -char2 - -char3 …) +procedure: (char>=? char1 char2 char3 …) These procedures return #t if the results of passing their arguments to char->integer @@ -5232,49 +5341,19 @@ monotonically non-decreasing, or monotonically non-increasing. These predicates are required to be transitive. -char library procedure: (char-ci=? - -char1 - -char2 - -char3 …) - - -char library procedure: (char-ci<? - -char1 +char library procedure: (char-ci=? char1 char2 char3 …) -char2 -char3 …) +char library procedure: (char-ci<? char1 char2 char3 …) -char library procedure: (char-ci>? +char library procedure: (char-ci>? char1 char2 char3 …) -char1 -char2 +char library procedure: (char-ci<=? char1 char2 char3 …) -char3 …) - -char library procedure: (char-ci<=? - -char1 - -char2 - -char3 …) - - -char library procedure: (char-ci>=? - -char1 - -char2 - -char3 …) +char library procedure: (char-ci>=? char1 char2 char3 …) These procedures are similar to char=? et cetera, but they treat upper case and lower @@ -5301,15 +5380,17 @@ char library procedure: (digit-value char) This procedure returns the numeric value (0 to 9) of its argument if it is a numeric digit (that is, if char-numeric? returns #t), or #f on any other character. +@example + (digit-value #\3) ⟹ 3 (digit-value #\x0664) ⟹ 4 (digit-value #\x0AE6) ⟹ 0 (digit-value #\x0EA6) ⟹ #f -procedure: (char->integer char) -procedure: (integer->char +@end example -n) +procedure: (char->integer char) +procedure: (integer->char n) Given a Unicode character, char->integer returns an exact integer between 0 and #xD7FF @@ -5413,14 +5494,10 @@ Returns #t if obj is a string, otherwise returns #f. -procedure: (make-string - -k) +procedure: (make-string k) -procedure: (make-string - -k char) +procedure: (make-string k char) The make-string procedure returns a newly allocated string of length @@ -5441,9 +5518,7 @@ Returns the number of characters in the given string. -procedure: (string-ref string - -k) +procedure: (string-ref string k) It is an error if @@ -5476,6 +5551,8 @@ k of string. There is no requirement for this procedure to execute in constant time. +@example + (define (f) (make-string 3 #\*)) (define (g) "***") (string-set! (f) 0 #\?) ⟹ unspecified @@ -5484,101 +5561,43 @@ string. There is no requirement for this procedure to execute in constant time. 0 #\?) ⟹ error -procedure: (string=? - -string1 - -string2 +@end example -string3 …) +procedure: (string=? string1 string2 string3 …) Returns #t if all the strings are the same length and contain exactly the same characters in the same positions, otherwise returns #f. -char library procedure: (string-ci=? - -string1 - -string2 - -string3 …) +char library procedure: (string-ci=? string1 string2 string3 …) Returns #t if, after case-folding, all the strings are the same length and contain the same characters in the same positions, otherwise returns #f. Specifically, these procedures behave as if string-foldcase were applied to their arguments before comparing them. -procedure: (string<? - -string1 - -string2 - -string3 …) - - -char library procedure: (string-ci<? +procedure: (string<? string1 string2 string3 …) -string1 -string2 +char library procedure: (string-ci<? string1 string2 string3 …) -string3 …) +procedure: (string>? string1 string2 string3 …) -procedure: (string>? -string1 +char library procedure: (string-ci>? string1 string2 string3 …) -string2 -string3 …) +procedure: (string<=? string1 string2 string3 …) -char library procedure: (string-ci>? +char library procedure: (string-ci<=? string1 string2 string3 …) -string1 -string2 +procedure: (string>=? string1 string2 string3 …) -string3 …) - -procedure: (string<=? - -string1 - -string2 - -string3 …) - - -char library procedure: (string-ci<=? - -string1 - -string2 - -string3 …) - - -procedure: (string>=? - -string1 - -string2 - -string3 …) - - -char library procedure: (string-ci>=? - -string1 - -string2 - -string3 …) +char library procedure: (string-ci>=? string1 string2 string3 …) These procedures return #t if their arguments are (respectively): monotonically @@ -5628,9 +5647,7 @@ start and ending with index end. This is equivalent to calling string-copy with the same arguments, but is provided for backward compatibility and stylistic flexibility. -procedure: (string-append - -string …) +procedure: (string-append string …) Returns a newly allocated string whose characters are the concatenation of the @@ -5701,11 +5718,15 @@ destination overlap, copying takes place as if the source is first copied into a string and then into the destination. This can be achieved without allocating storage by making sure to copy in the correct direction in such circumstances. +@example + (define a "12345") (define b (string-copy "abcde")) (string-copy! b 1 a 0 2) b ⟹ "a12de" +@end example + procedure: (string-fill! string fill) procedure: (string-fill! string fill start) procedure: (string-fill! string fill start end) @@ -5765,8 +5786,12 @@ procedure: (vector obj …) Returns a newly allocated vector whose elements contain the given arguments. It is analogous to list. +@example + (vector 'a 'b 'c) ⟹ #(a b c) +@end example + procedure: (vector-length vector) Returns the number of elements in @@ -5787,6 +5812,8 @@ k of vector. +@example + (vector-ref '#(1 1 2 3 5 8 13 21) 5) ⟹ 8 @@ -5795,6 +5822,8 @@ vector. (round (* 2 (acos -1))))) ⟹ 13 +@end example + procedure: (vector-set! vector k obj) It is an error if @@ -5811,6 +5840,8 @@ k of vector. +@example + (let ((vec (vector 0 '(2 2 2 2) "Anna"))) (vector-set! vec 1 '("Sue" "Sue")) vec) @@ -5819,6 +5850,8 @@ vector. (vector-set! '#(0 1 2) 1 "doe") ⟹ error ; constant vector +@end example + procedure: (vector->list vector) procedure: (vector->list vector start) procedure: (vector->list vector start end) @@ -5838,6 +5871,8 @@ list. In both procedures, order is preserved. +@example + (vector->list '#(dah dah didah)) ⟹ (dah dah didah) (vector->list '#(dah dah didah) 1 2) @@ -5845,6 +5880,8 @@ In both procedures, order is preserved. (list->vector '(dididit dah)) ⟹ #(dididit dah) +@end example + procedure: (vector->string vector) procedure: (vector->string vector start) procedure: (vector->string vector start end) @@ -5878,10 +5915,14 @@ end. In both procedures, order is preserved. +@example + (string->vector "ABC") ⟹ #(#\A #\B #\C) (vector->string #(#\1 #\2 #\3) ⟹ "123" +@end example + procedure: (vector-copy vector) procedure: (vector-copy vector start) procedure: (vector-copy vector start end) @@ -5895,6 +5936,8 @@ start and end. The elements of the new vector are the same (in the sense of eqv?) as the elements of the old. +@example + (define a #(1 8 2 8)) ; a may be immutable (define b (vector-copy a)) (vector-set! b 0 3) ; b is mutable @@ -5902,6 +5945,8 @@ b ⟹ #(3 8 2 8) (define c (vector-copy b 1 3)) c ⟹ #(8 2) +@end example + procedure: (vector-copy! to at from) procedure: (vector-copy! to at from start) procedure: (vector-copy! to at from start end) @@ -5935,22 +5980,28 @@ destination overlap, copying takes place as if the source is first copied into a vector and then into the destination. This can be achieved without allocating storage by making sure to copy in the correct direction in such circumstances. +@example + (define a (vector 1 2 3 4 5)) (define b (vector 10 20 30 40 50)) (vector-copy! b 1 a 0 2) b ⟹ #(10 1 2 40 50) -procedure: (vector-append +@end example -vector …) +procedure: (vector-append vector …) Returns a newly allocated vector whose elements are the concatenation of the elements of the given vectors. +@example + (vector-append #(a b c) #(d e f)) ⟹ #(a b c d e f) +@end example + procedure: (vector-fill! vector fill) procedure: (vector-fill! vector fill start) procedure: (vector-fill! vector fill start end) @@ -5965,11 +6016,15 @@ start and end. +@example + (define a (vector 1 2 3 4 5)) (vector-fill! a 'smash 2 4) a ⟹ #(1 2 smash smash 5) +@end example + @node Bytevectors @section Bytevectors @@ -6007,18 +6062,24 @@ byte is given, then all elements of the bytevector are initialized to byte, otherwise the contents of each element are unspecified. +@example + (make-bytevector 2 12) ⟹ #u8(12 12) -procedure: (bytevector +@end example -byte …) +procedure: (bytevector byte …) Returns a newly allocated bytevector containing its arguments. +@example + (bytevector 1 3 5 1 3 5) ⟹ #u8(1 3 5 1 3 5) (bytevector) ⟹ #u8() +@end example + procedure: (bytevector-length bytevector) Returns the length of @@ -6039,10 +6100,14 @@ kth byte of bytevector. +@example + (bytevector-u8-ref '#u8(1 1 2 3 5 8 13 21) 5) ⟹ 8 +@end example + procedure: (bytevector-u8-set! bytevector k byte) It is an error if @@ -6059,11 +6124,15 @@ kth byte of bytevector. +@example + (let ((bv (bytevector 1 2 3 4))) (bytevector-u8-set! bv 1 3) bv) ⟹ #u8(1 3 3 4) +@end example + procedure: (bytevector-copy bytevector) procedure: (bytevector-copy bytevector start) procedure: (bytevector-copy bytevector start end) @@ -6076,9 +6145,13 @@ start and end. +@example + (define a #u8(1 2 3 4 5)) (bytevector-copy a 2 4)) ⟹ #u8(3 4) +@end example + procedure: (bytevector-copy! to at from) procedure: (bytevector-copy! to at from start) procedure: (bytevector-copy! to at from start end) @@ -6112,25 +6185,31 @@ destination overlap, copying takes place as if the source is first copied into a bytevector and then into the destination. This can be achieved without allocating storage by making sure to copy in the correct direction in such circumstances. +@example + (define a (bytevector 1 2 3 4 5)) (define b (bytevector 10 20 30 40 50)) (bytevector-copy! b 1 a 0 2) b ⟹ #u8(10 1 2 40 50) - Note: This procedure appears in R6RS, but places the source before the destination, - contrary to other such procedures in Scheme. +@end example -procedure: (bytevector-append +Note: This procedure appears in R6RS, but places the source before the destination, + contrary to other such procedures in Scheme. -bytevector …) +procedure: (bytevector-append bytevector …) Returns a newly allocated bytevector whose elements are the concatenation of the elements in the given bytevectors. +@example + (bytevector-append #u8(0 1 2) #u8(3 4 5)) ⟹ #u8(0 1 2 3 4 5) +@end example + procedure: (utf8->string bytevector) procedure: (utf8->string bytevector start) procedure: (utf8->string bytevector start end) @@ -6155,9 +6234,13 @@ start and end and returns the corresponding bytevector. +@example + (utf8->string #u8(#x41)) ⟹ "A" (string->utf8 "λ") ⟹ #u8(#xCE #xBB) +@end example + @node Control features @section Control features @@ -6172,6 +6255,8 @@ Returns #t if obj is a procedure, otherwise returns #f. +@example + (procedure? car) ⟹ #t (procedure? 'car) ⟹ #f (procedure? (lambda (x) (* x x))) @@ -6181,18 +6266,16 @@ obj is a procedure, otherwise returns #f. (call-with-current-continuation procedure?) ⟹ #t -procedure: (apply proc +@end example -arg1 … args) +procedure: (apply proc arg1 … args) The apply procedure calls -proc with the elements of the list (append (list +proc with the elements of the list @code{(append (list arg1 …) args)} as the actual arguments. -arg1 …) - -args) as the actual arguments. +@example (apply + (list 3 4)) ⟹ 7 @@ -6203,11 +6286,9 @@ args) as the actual arguments. ((compose sqrt *) 12 75) ⟹ 30 -procedure: (map proc - -list1 +@end example -list2 …) +procedure: (map proc list1 list2 …) It is an error if @@ -6232,6 +6313,8 @@ proc is applied to the elements of the lists is unspecified. If multiple returns occur from map, the values returned by earlier returns are not mutated. +@example + (map cadr '((a b) (d e) (g h))) ⟹ (b e h) @@ -6249,11 +6332,9 @@ returns are not mutated. or (2 1) -procedure: (string-map proc - -string1 +@end example -string2 …) +procedure: (string-map proc string1 string2 …) It is an error if @@ -6275,6 +6356,8 @@ proc is applied to the elements of the strings is unspecified. If multiple returns occur from string-map, the values returned by earlier returns are not mutated. +@example + (string-map char-foldcase "AbdEgH") ⟹ "abdegh" @@ -6292,11 +6375,9 @@ earlier returns are not mutated. "ululululul") ⟹ "StUdLyCaPs" -procedure: (vector-map proc - -vector1 +@end example -vector2 …) +procedure: (vector-map proc vector1 vector2 …) It is an error if @@ -6317,6 +6398,8 @@ proc is applied to the elements of the vectors is unspecified. If multiple returns occur from vector-map, the values returned by earlier returns are not mutated. +@example + (vector-map cadr '#((a b) (d e) (g h))) ⟹ #(b e h) @@ -6336,11 +6419,9 @@ earlier returns are not mutated. or #(2 1) -procedure: (for-each proc - -list1 +@end example -list2 …) +procedure: (for-each proc list1 list2 …) It is an error if @@ -6366,17 +6447,17 @@ It is an error for proc to mutate any of the lists. +@example + (let ((v (make-vector 5))) (for-each (lambda (i) (vector-set! v i (* i i))) '(0 1 2 3 4)) v) ⟹ #(0 1 4 9 16) -procedure: (string-for-each proc - -string1 +@end example -string2 …) +procedure: (string-for-each proc string1 string2 …) It is an error if @@ -6399,17 +6480,17 @@ the shortest string runs out. It is an error for proc to mutate any of the strings. +@example + (let ((v '())) (string-for-each (lambda (c) (set! v (cons (char->integer c) v))) "abcde") v) ⟹ (101 100 99 98 97) -procedure: (vector-for-each proc - -vector1 +@end example -vector2 …) +procedure: (vector-for-each proc vector1 vector2 …) It is an error if @@ -6432,12 +6513,16 @@ the shortest vector runs out. It is an error for proc to mutate any of the vectors. +@example + (let ((v (make-list 5))) (vector-for-each (lambda (i) (list-set! v i (* i i))) '#(0 1 2 3 4)) v) ⟹ (0 1 4 9 16) +@end example + procedure: (call-with-current-continuation proc) procedure: (call/cc proc) @@ -6480,6 +6565,8 @@ call-with-current-continuation is used. If all real uses were as simple as these there would be no need for a procedure with the power of call-with-current-continuation. +@example + (call-with-current-continuation (lambda (exit) (for-each (lambda (x) @@ -6504,7 +6591,9 @@ call-with-current-continuation. (list-length '(a b . c)) ⟹ #f - Rationale: A common use of call-with-current-continuation is for structured, +@end example + +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 @@ -6528,10 +6617,14 @@ procedure: (values obj …) Delivers all of its arguments to its continuation. The values procedure might be defined as follows: +@example + (define (values . things) (call-with-current-continuation (lambda (cont) (apply cont things)))) +@end example + procedure: (call-with-values producer consumer) Calls its @@ -6543,12 +6636,16 @@ consumer procedure with those values as arguments. The continuation for the call consumer is the continuation of the call to call-with-values. +@example + (call-with-values (lambda () (values 4 5)) (lambda (a b) b)) ⟹ 5 (call-with-values * -) ⟹ -1 +@end example + procedure: (dynamic-wind before thunk after) Calls @@ -6617,6 +6714,8 @@ before or after is unspecified. +@example + (let ((path '()) (c #f)) (let ((add (lambda (s) @@ -6636,6 +6735,8 @@ after is unspecified. ⟹ (connect talk1 disconnect connect talk2 disconnect) +@end example + @node Exceptions @section Exceptions @@ -6652,11 +6753,7 @@ object encapsulating information about the exception. Any procedure accepting on argument can serve as an exception handler and any object can be used to represent an exception. -procedure: (with-exception-handler - -handler - -thunk) +procedure: (with-exception-handler handler thunk) It is an error if @@ -6674,6 +6771,8 @@ for the invocation of thunk. +@example + (call-with-current-continuation (lambda (k) (with-exception-handler @@ -6695,9 +6794,9 @@ thunk. prints something went wrong After printing, the second example then raises another exception. -procedure: (raise +@end example -obj) +procedure: (raise obj) Raises an exception by invoking the current exception handler on @@ -6709,9 +6808,7 @@ same dynamic environment as the handler. The relationship between obj and the object raised by the secondary exception is unspecified. -procedure: (raise-continuable - -obj) +procedure: (raise-continuable obj) Raises an exception by invoking the current exception handler on @@ -6722,6 +6819,8 @@ place when the handler being called was installed, and (2) if the handler being returns, then it will again become the current exception handler. If the handler returns, the values it returns become the values returned by the call to raise-continuable. +@example + (with-exception-handler (lambda (con) (cond @@ -6736,11 +6835,9 @@ the values it returns become the values returned by the call to raise-continuabl prints: should be a number ⟹ 65 -procedure: (error - -message +@end example -obj …) +procedure: (error message obj …) Message should be a string. @@ -6752,6 +6849,8 @@ message, as well as any objs, known as the irritants. The procedure error-object? must return #t on such objects. +@example + (define (null-list? l) (cond ((pair? l) #f) ((null? l) #t) @@ -6760,6 +6859,8 @@ objs, known as the irritants. The procedure error-object? must return #t on such "null-list?: argument out of domain" l)))) +@end example + procedure: (error-object? obj) Returns #t if @@ -6791,9 +6892,7 @@ output port on a file, respectively. Otherwise, it returns #f. @node Environments and evaluation @section Environments and evaluation -eval library procedure: (environment - -list1 …) +eval library procedure: (environment list1 …) This procedure returns a specifier for the environment that results by starting with an @@ -6863,6 +6962,8 @@ returned. If it is a definition, the specified identifier(s) are defined in the environment, provided the environment is not immutable. Implementations may extend eval to allow other objects. +@example + (eval '(* 7 3) (environment '(scheme base))) ⟹ 21 @@ -6874,6 +6975,8 @@ eval to allow other objects. (environment '(scheme base))) ⟹ error is signaled +@end example + @node Input and output @section Input and output @@ -7044,6 +7147,8 @@ port was not created with open-output-string. Returns a string consisting of the characters that have been output to the port so far in the order they were output. If the result string is modified, the effect is unspecified. +@example + (parameterize ((current-output-port (open-output-string))) @@ -7055,6 +7160,8 @@ the order they were output. If the result string is modified, the effect is unsp ⟹ "piece by piece by piece.\n" +@end example + procedure: (open-input-bytevector bytevector) Takes a bytevector and returns a binary input port that delivers bytes from the @@ -7486,9 +7593,13 @@ to encode the name and decode the value of the environment variable. It is an er get-environment-variable can’t decode the value. It is also an error to mutate the resulting string. +@example + (get-environment-variable "PATH") ⟹ "/usr/local/bin:/usr/bin:/bin" +@end example + process-context library procedure: (get-environment-variables) Returns the names and values of all the environment variables as an alist, where the car @@ -7496,9 +7607,13 @@ of each entry is the name of an environment variable and the cdr is its value, b strings. The order of the list is unspecified. It is an error to mutate any of these strings or the alist itself. +@example + (get-environment-variables) ⟹ (("USER" . "root") ("HOME" . "/")) +@end example + time library procedure: (current-second) Returns an inexact number representing the current time on the International Atomic @@ -7531,6 +7646,8 @@ time library procedure: (jiffies-per-second) Returns an exact integer representing the number of jiffies per SI second. This value is an implementation-specified constant. +@example + (define (time-length) (let ((list (make-list 100000)) (start (current-jiffy))) @@ -7538,11 +7655,15 @@ an implementation-specified constant. (/ (- (current-jiffy) start) (jiffies-per-second)))) +@end example + procedure: (features) Returns a list of the feature identifiers which cond-expand treats as true. It is an error to modify this list. Here is an example of what features might return: +@example + (features) ⟹ (r7rs ratios exact-complex full-unicode gnu-linux little-endian @@ -7550,6 +7671,8 @@ modify this list. Here is an example of what features might return: fantastic-scheme-1.0 space-ship-control-system) +@end example + @node Formal syntax and semantics @chapter Formal syntax and semantics @@ -7996,6 +8119,8 @@ quasiquote. Conditional derived syntax types: +@example + (define-syntax cond (syntax-rules (else =>) ((cond (else result1 result2 ...)) @@ -8021,6 +8146,7 @@ Conditional derived syntax types: (if test (begin result1 result2 ...) (cond clause1 clause2 ...))))) + (define-syntax case (syntax-rules (else =>) ((case (key ...) @@ -8053,12 +8179,14 @@ Conditional derived syntax types: (if (memv key '(atoms ...)) (begin result1 result2 ...) (case key clause clauses ...))))) + (define-syntax and (syntax-rules () ((and) #t) ((and test) test) ((and test1 test2 ...) (if test1 (and test2 ...) #f)))) + (define-syntax or (syntax-rules () ((or) #f) @@ -8066,18 +8194,25 @@ Conditional derived syntax types: ((or test1 test2 ...) (let ((x test1)) (if x x (or test2 ...)))))) + (define-syntax when (syntax-rules () ((when test result1 result2 ...) (if test (begin result1 result2 ...))))) + (define-syntax unless (syntax-rules () ((unless test result1 result2 ...) (if (not test) (begin result1 result2 ...))))) + +@end example + Binding constructs: +@example + (define-syntax let (syntax-rules () ((let ((name val) ...) body1 body2 ...) @@ -8088,6 +8223,7 @@ Binding constructs: body1 body2 ...))) tag) val ...)))) + (define-syntax let* (syntax-rules () ((let* () body1 body2 ...) @@ -8097,12 +8233,17 @@ Binding constructs: (let ((name1 val1)) (let* ((name2 val2) ...) body1 body2 ...))))) + +@end example + The following letrec macro uses the symbol <undefined> in place of an expression which returns something that when stored in a location makes it an error to try to obtain the value stored in the location. (No such expression is defined in Scheme.) A trick is used to generate the temporary names needed to avoid specifying the order in which the values are evaluated. This could also be accomplished by using an auxiliary macro. +@example + (define-syntax letrec (syntax-rules () ((letrec ((var1 init1) ...) body ...) @@ -8131,102 +8272,113 @@ are evaluated. This could also be accomplished by using an auxiliary macro. (newtemp temp ...) ((var1 init1) ...) body ...)))) + (define-syntax letrec* (syntax-rules () ((letrec* ((var1 init1) ...) body1 body2 ...) (let ((var1 <undefined>) ...) (set! var1 init1) ... - (let () body1 body2 ...))))) (define-syntax let-values + (let () body1 body2 ...))))) + +(define-syntax let-values (syntax-rules () ((let-values (binding ...) body0 body1 ...) (let-values "bind" - (binding ...) () (begin body0 body1 ...))) + (binding ...) () (begin body0 body1 ...))) ((let-values "bind" () tmps body) (let tmps body)) ((let-values "bind" ((b0 e0) - binding ...) tmps body) + binding ...) tmps body) (let-values "mktmp" b0 e0 () - (binding ...) tmps body)) + (binding ...) tmps body)) ((let-values "mktmp" () e0 args - bindings tmps body) + bindings tmps body) (call-with-values - (lambda () e0) + (lambda () e0) (lambda args (let-values "bind" - bindings tmps body)))) + bindings tmps body)))) ((let-values "mktmp" (a . b) e0 (arg ...) - bindings (tmp ...) body) + bindings (tmp ...) body) (let-values "mktmp" b e0 (arg ... x) - bindings (tmp ... (a x)) body)) + bindings (tmp ... (a x)) body)) ((let-values "mktmp" a e0 (arg ...) - bindings (tmp ...) body) + bindings (tmp ...) body) (call-with-values - (lambda () e0) + (lambda () e0) (lambda (arg ... . x) (let-values "bind" - bindings (tmp ... (a x)) body)))))) + bindings (tmp ... (a x)) body)))))) + (define-syntax let*-values (syntax-rules () ((let*-values () body0 body1 ...) (let () body0 body1 ...)) ((let*-values (binding0 binding1 ...) - body0 body1 ...) + body0 body1 ...) (let-values (binding0) (let*-values (binding1 ...) body0 body1 ...))))) + (define-syntax define-values (syntax-rules () ((define-values () expr) (define dummy (call-with-values (lambda () expr) - (lambda args #f)))) + (lambda args #f)))) ((define-values (var) expr) (define var expr)) ((define-values (var0 var1 ... varn) expr) (begin (define var0 (call-with-values (lambda () expr) - list)) + list)) (define var1 (let ((v (cadr var0))) (set-cdr! var0 (cddr var0)) v)) ... - (define varn - (let ((v (cadr var0))) - (set! var0 (car var0)) - v)))) + (define varn + (let ((v (cadr var0))) + (set! var0 (car var0)) + v)))) ((define-values (var0 var1 ... . varn) expr) (begin (define var0 (call-with-values (lambda () expr) - list)) + list)) (define var1 (let ((v (cadr var0))) (set-cdr! var0 (cddr var0)) v)) ... - (define varn - (let ((v (cdr var0))) - (set! var0 (car var0)) - v)))) + (define varn + (let ((v (cdr var0))) + (set! var0 (car var0)) + v)))) ((define-values var expr) (define var (call-with-values (lambda () expr) - list))))) + list))))) + (define-syntax begin (syntax-rules () ((begin exp ...) ((lambda () exp ...))))) + +@end example + The following alternative expansion for begin does not make use of the ability to write more than one expression in the body of a lambda expression. In any case, note that these rules apply only if the body of the begin contains no definitions. +@example + (define-syntax begin (syntax-rules () ((begin exp) @@ -8236,59 +8388,111 @@ these rules apply only if the body of the begin contains no definitions. (lambda () exp1) (lambda args (begin exp2 ...)))))) + +@end example + The following syntax definition of do uses a trick to expand the variable clauses. As with letrec above, an auxiliary macro would also work. The expression (if #f #f) is used to obtain an unspecific value. +@example + (define-syntax do (syntax-rules () ((do ((var init step ...) ...) (test expr ...) - command ...) + command ...) (letrec - ((loop - (lambda (var ...) - (if test - (begin - (if #f #f) - expr ...) - (begin - command - ... - (loop (do "step" var step ...) - ...)))))) + ((loop + (lambda (var ...) + (if test + (begin + (if #f #f) + expr ...) + (begin + command + ... + (loop (do "step" var step ...) + ...)))))) (loop init ...))) ((do "step" x) x) ((do "step" x y) y))) -Here is a possible implementation of delay, force and delay-force. We define the -expression -(delay-force <expression>) to have the same meaning as the procedure call +@end example + +Here is a possible implementation of delay, force and delay-force. We +define the expression + +@example + +(delay-force <expression>) -(make-promise #f (lambda () <expression>)) as follows +@end example + +to have the same meaning as the procedure call + +@example + +(make-promise #f (lambda () <expression>)) + +@end example + +as follows + +@example (define-syntax delay-force (syntax-rules () ((delay-force expression) - (make-promise #f (lambda () expression))))) and we define the expression + (make-promise #f (lambda () expression))))) + +@end example + +and we define the expression + +@example + +(delay <expression>) -(delay <expression>) to have the same meaning as: +@end example + +to have the same meaning as: + +@example + +(delay-force (make-promise #t <expression>)) + +@end example + +as follows -(delay-force (make-promise #t <expression>)) as follows +@example (define-syntax delay (syntax-rules () ((delay expression) - (delay-force (make-promise #t expression))))) where make-promise is defined as -follows: + (delay-force (make-promise #t expression))))) + +@end example + +where make-promise is defined as follows: + +@example (define make-promise (lambda (done? proc) - (list (cons done? proc)))) Finally, we define force to call the procedure expressions in -promises iteratively using a trampoline technique following [38] until a non-lazy result -(i.e. a value created by delay instead of delay-force) is returned, as follows: + (list (cons done? proc)))) + +@end example + +Finally, we define force to call the procedure expressions in promises +iteratively using a trampoline technique following [38] until a +non-lazy result (i.e. a value created by delay instead of delay-force) +is returned, as follows: + +@example (define (force promise) (if (promise-done? promise) @@ -8296,7 +8500,13 @@ promises iteratively using a trampoline technique following [38] until a non-laz (let ((promise* ((promise-value promise)))) (unless (promise-done? promise) (promise-update! promise* promise)) - (force promise)))) with the following promise accessors: + (force promise)))) + +@end example + +with the following promise accessors: + +@example (define promise-done? (lambda (x) (car (car x)))) @@ -8306,11 +8516,17 @@ promises iteratively using a trampoline technique following [38] until a non-laz (lambda (new old) (set-car! (car old) (promise-done? new)) (set-cdr! (car old) (promise-value new)) - (set-car! new (car old)))) The following implementation of make-parameter and + (set-car! new (car old)))) + +@end example + +The following implementation of make-parameter and parameterize is suitable for an implementation with no threads. Parameter objects are implemented here as procedures, using two arbitrary unique objects <param-set!> and <param-convert>: +@example + (define (make-parameter init . o) (let* ((converter (if (pair? o) (car o) (lambda (x) x))) @@ -8324,9 +8540,15 @@ implemented here as procedures, using two arbitrary unique objects <param-set!> ((eq? (car args) <param-convert>) converter) (else - (error "bad parameter syntax")))))) Then parameterize uses dynamic-wind to + (error "bad parameter syntax")))))) + +@end example + +Then parameterize uses dynamic-wind to dynamically rebind the associated value: +@example + (define-syntax parameterize (syntax-rules () ((parameterize ("step") @@ -8353,9 +8575,14 @@ dynamically rebind the associated value: () ((param value) ...) body)))) + +@end example + The following implementation of guard depends on an auxiliary macro, here called guard-aux. +@example + (define-syntax guard (syntax-rules () ((guard (var clause ...) e1 e2 ...) @@ -8413,6 +8640,7 @@ guard-aux. (if test (begin result1 result2 ...) (guard-aux reraise clause1 clause2 ...))))) + (define-syntax case-lambda (syntax-rules () ((case-lambda (params body0 ...) ...) @@ -8438,9 +8666,13 @@ guard-aux. (cl . rest)))))) (cl (params body0 ...) ...))))))) +@end example + This definition of cond-expand does not interact with the features procedure. It requires that each feature identifier provided by the implementation be explicitly mentioned. +@example + (define-syntax cond-expand ;; Extend this to mention all feature ids and libraries (syntax-rules (and or not else r7rs library scheme base) @@ -8500,6 +8732,8 @@ that each feature identifier provided by the implementation be explicitly mentio more-clauses ...) (cond-expand more-clauses ...)))) +@end example + @node Appendices @chapter Appendices @@ -9303,6 +9537,8 @@ The procedure runge-kutta-4 takes a function, f, that produces a system derivative from a system state. It produces a function that takes a system state and produces a new system state. +@example + (define (runge-kutta-4 f h) (let ((*h (scale-vector h)) (*2 (scale-vector 2)) @@ -9342,20 +9578,34 @@ produces a new system state. (define add-vectors (elementwise +)) (define (scale-vector s) - (elementwise (lambda (x) (* x s)))) The map-streams procedure is analogous to map: it + (elementwise (lambda (x) (* x s)))) + +@end example + +The map-streams procedure is analogous to map: it applies its first argument (a procedure) to all the elements of its second argument (a stream). +@example + (define (map-streams f s) (cons (f (head s)) - (delay (map-streams f (tail s))))) Infinite streams are implemented as pairs whose car + (delay (map-streams f (tail s))))) + +@end example + +Infinite streams are implemented as pairs whose car holds the first element of the stream and whose cdr holds a promise to deliver the rest of the stream. +@example + (define head car) (define (tail stream) (force (cdr stream))) +@end example + The following illustrates the use of integrate-system in integrating the system C dvC = −iL vC @@ -9368,6 +9618,8 @@ The following illustrates the use of integrate-system in integrating the system which models a damped oscillator. +@example + (define (damped-oscillator R L C) (lambda (state) (let ((Vc (vector-ref state 0)) @@ -9381,6 +9633,8 @@ which models a damped oscillator. '#(1 0) .01)) +@end example + @node References @chapter References