From 226d3ca84fb2b414d4e162e0ad6d56c16ecca147 Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Thu, 15 Dec 2016 18:37:50 +0000 Subject: [PATCH] Sync --- docs/api/scheme/base.md | 274 +++++++++++++++++++++++++++++++++ docs/api/scheme/case-lambda.md | 16 ++ 2 files changed, 290 insertions(+) diff --git a/docs/api/scheme/base.md b/docs/api/scheme/base.md index dbf681e2..11152800 100644 --- a/docs/api/scheme/base.md +++ b/docs/api/scheme/base.md @@ -168,8 +168,17 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # and +*Syntax* + (and {test1} ...) +Semantics: The `{test}` expressions are evaluated from left to right, and if any expression evaluates to `#f`, then `#f` is returned. Any remaining expressions are not 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. + + (and (= 2 2) (> 2 1)) => #t + (and (= 2 2) (< 2 1)) => #f + (and 1 2 '(f g)) => (f g) + (and) => #t + # any (any pred lst) @@ -194,8 +203,27 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # begin +*Syntax* + (begin {expression or definition} ...) +This form of `begin` can appear as part of a `{body}`, or at the outermost level of a `{program}`, or at the REPL, or directly nested in a begin that is itself of this form. It causes the contained expressions and definitions to be evaluated exactly as if the enclosing begin construct were not present. + +Rationale: This form is commonly used in the output of macros which need to generate multiple definitions and splice them into the context in which they are expanded. + + (begin {expression1} {expression2} ...) + +This form of `begin` can be used as an ordinary expression. The `{expression}`'s are evaluated sequentially from left to right, and the values of the last `{expression}` are returned. This expression type is used to sequence side effects such as assignments or input and output. + + (define x 0) + + (and (= x 0) + (begin (set! x 5) + (+ x 1))) => 6 + + (begin (display "4 plus 1 equals ") + (display (+ 4 1))) => unspecified and prints 4 plus 1 equals 5 + # boolean=? (boolean=? b1 b2 ...) @@ -234,8 +262,43 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # case +*Syntax* + (case {key} {clause1} {clause2} ...) +Syntax: `{Key}` can be any expression. Each `{clause}` has the form + + (({datum1} ...) {expression1} {expression2} ...), + +where each `{datum}` is an external representation of some object. It is an error if any of the `{datum}`'s are the same anywhere in the expression. Alternatively, a `{clause}` can be of the form + + ((hdatum1} ...) => {expression}) + +The last `{clause}` can be an "else clause," which has one of the forms + + (else {expression1} {expression2} . . . ) + +or + + (else => {expression}). + +Semantics: A `case` expression is evaluated as follows. `{Key}` is evaluated and its result is compared against each `{datum}`. If the result of evaluating `{key}` is the same to a `{datum}`, then the expressions in the corresponding `{clause}` are evaluated in order and the results of the last expression in the `{clause}` are returned as the results of the case expression. + +If the result of evaluating `{key}` is different from every `{datum}`, then if there is an else clause, its expressions are evaluated and the results of the last are the results of the case expression; otherwise the result of the case expression is unspecified. + +If the selected `{clause}` or else clause uses the `=>` alternate form, then the `{expression}` is evaluated. It is an error if its value is not a procedure accepting one argument. This procedure is then called on the value of the `{key}` and the values returned by this procedure are returned by the case expression. + + (case (* 2 3) + ((2 3 5 7) 'prime) + ((1 4 6 8 9) 'composite)) => composite + (case (car '(c d)) + ((a) 'a) + ((b) 'b)) => unspecified + (case (car '(c d)) + ((a e i o u) 'vowel) + ((w y) 'semivowel) + (else => (lambda (x) x))) => c + # ceiling (ceiling z) @@ -266,12 +329,81 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # cond +*Syntax* + (cond {clause1} {clause2} ...) + else + => + +Syntax: `{Clauses}` take one of two forms, either + + ({test} {expression1} ...) + +where `{test}` is any expression, or + + ({test} => {expression}) + +The last `{clause}` can be an "else clause," which has the +form + + (else {expression1} {expression2} ...) + +Semantics: A `cond` expression is evaluated by evaluating +the `{test}` expressions of successive `{clause}`'s in order until +one of them evaluates to a true value. +When a `{test}` evaluates to a true value, the remaining + `{expression}`'s in its `{clause}` are evaluated in order, and the +results of the last `{expression}` in the `{clause}` are returned +as the results of the entire cond expression. + +If the selected `{clause}` contains only the `{test}` and no + `{expression}`'s, then the value of the `{test}` is returned as +the result. If the selected `{clause}` uses the `=>` alternate +form, then the `{expression}` is evaluated. It is an error if +its value is not a procedure that accepts one argument. +This procedure is then called on the value of the `{test}` and +the values returned by this procedure are returned by the +cond expression. + +If all `{test}`'s evaluate to `#f`, and there is no else clause, +then the result of the conditional 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. + + (cond ((> 3 2) 'greater) + ((< 3 2) 'less)) => greater + (cond ((> 3 3) 'greater) + ((< 3 3) 'less) + (else 'equal)) => equal + (cond ((assv 'b '((a 1) (b 2))) => cadr) + (else #f)) => 2 # cond-expand +*Syntax* + (cond-expand {ce-clause2} {ce-clause2} ...) +Syntax: The `cond-expand` expression type provides a way to statically expand different expressions depending on the implementation. A `{ce-clause}` takes the following form: + + ({feature requirement} {expression} ...) + +The last clause can be an "else clause," which has the form + + (else {expression} ...) + +A `{feature requirement}` takes one of the following forms: + +- `{feature identifier}` +- `(library {library name})` +- `(and {feature requirement} ...)` +- `(or {feature requirement} ...)` +- `(not {feature requirement})` + +Semantics: Each Scheme implementation maintains a list of feature identifiers which are present, as well as a list of libraries which can be imported. The value of a `{feature requirement}` is determined by replacing each `{feature identifier}` and `(library {library name})` on the implementation’s lists with `#t`, and all other feature identifiers and library names with `#f`, then evaluating the resulting expression as a Scheme boolean expression under the normal interpretation of `and`, `or`, and `not`. + +A `cond-expand` is then expanded by evaluating the `{feature requirement}`'s of successive `{ce-clause}`'s in order until one of them returns `#t`. When a true clause is found, the corresponding `{expression}`'s are expanded to a begin, and the remaining clauses are ignored. If none of the `{feature requirement}`'s evaluate to `#t`, then if there is an else clause, its `{expression}`'s are included. Otherwise, the behavior of the cond-expand is unspecified. Unlike cond, `cond-expand` does not depend on the value of any variables. + # current-error-port (current-error-port) @@ -286,6 +418,8 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # define-record-type +*Syntax* + (define-record-type {name} {constructor} {pred} {field} ...) @@ -296,6 +430,8 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # do +*Syntax* + (do (({variable1} {init1} {step1}) ...) @@ -392,6 +528,8 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # guard +*Syntax* + (guard ({variable} {cond clause1} {cond clause2} ...) @@ -420,28 +558,126 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # let +*Syntax* + (let {bindings} {body}) +`{bindings}` has the form: + + (({variable1} {init1}) ...) + +where each `{init}` is an expression, and `{body}` is a sequence +of zero or more definitions followed by a sequence of one or more expressions. It is an error for a `{variable}` to appear more than once in the list of variables being bound. + +Semantics: The `{init}`'s are evaluated in the current environment (in some unspecified order), the `{variable}`'s are bound to fresh locations holding the results, the `{body}` is 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. + + (let ((x 2) (y 3)) + (* x y)) => 6 + + (let ((x 2) (y 3)) + (let ((x 7) + (z (+ x y))) + (* z x))) => 35 + # let* +*Syntax* + (let* {bindings} {body}) +`{bindings}` has the form: + + (({variable1} {init1}) ...) + +where each `{init}` is an expression, and `{body}` is a sequence +of zero or more definitions followed by a sequence of one or more expressions. It is an error for a `{variable}` to appear more than once in the list of variables being bound. + +Semantics: The `let*` binding construct is similar to `let`, but the bindings are performed sequentially from left to right, and the region of a binding indicated by `({variable} {init})` is that part of the `let*` expression to the right of the binding. Thus the second binding is done in an environment in which the first binding is visible, and so on. + +The `{variable}`'s need not be distinct. + + (let ((x 2) (y 3)) + (let* ((x 7) + (z (+ x y))) + (* z x))) => 70 + + # let*-values +*Syntax* + (let*-values {mv binding spec} {body}) # let-values +*Syntax* + (let-values {mv binding spec} {body}) # letrec +*Syntax* + (letrec {bindings} {body}) +`{bindings}` has the form: + + (({variable1} {init1}) ...) + +where each `{init}` is an expression, and `{body}` is a sequence +of zero or more definitions followed by a sequence of one or more expressions. It is an error for a `{variable}` to appear more than once in the list of variables being bound. + +Semantics: The `{variable}`'s are bound to fresh locations holding unspecified values, the `{init}`'s are evaluated in the resulting environment (in some unspecified order), each `{variable}` is assigned to the result of the corresponding `{init}`, the `{body}` is evaluated in the resulting environment, and the values of the last expression in `{body}` are returned. + +Each binding of a `{variable}` has the entire letrec expression +as its region, making it possible to define mutually +recursive procedures. + + (letrec ((even? + (lambda (n) + (if (zero? n) + #t + (odd? (- n 1))))) + (odd? + (lambda (n) + (if (zero? n) + #f + (even? (- n 1)))))) + (even? 88)) + => #t + +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 letrec, all the `{init}`'s are lambda expressions and the restriction is satisfied automatically. + # letrec* +*Syntax* + (letrec* {bindings} {body}) +`{bindings}` has the form: + + (({variable1} {init1}) ...) + +where each `{init}` is an expression, and `{body}` is a sequence +of zero or more definitions followed by a sequence of one or more expressions. It is an error for a `{variable}` to appear more than once in the list of variables being bound. + +Semantics: The `{variable}`'s are bound to fresh locations, each `{variable}` is assigned in left-to-right order to the result of evaluating the corresponding `{init}`, the `{body}` is evaluated in the resulting environment, and the values of the last expression in `{body}` are returned. Despite the left-to-right evaluation and assignment order, each binding of a `{variable}` has the entire `letrec*` expression as its region, making it possible to define mutually recursive procedures. + +If it is not possible to evaluate each `{init}` without assigning or referring to the value of the corresponding `{variable}` or the `{variable}` of any of the bindings that follow it in `{bindings}`, it is an error. Another restriction is that it is an error to invoke the continuation of an `{init}` more than once. + + (letrec* ((p + (lambda (x) + (+ 1 (q (- x 1))))) + (q + (lambda (y) + (if (zero? y) + 0 + (+ 1 (p (- y 1)))))) + (x (p 5)) + (y x)) + y) + => 5 + # list (list obj ...) @@ -570,8 +806,18 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # or +*Syntax* + (or {test1} ...) +Semantics: The `{test}` expressions are evaluated from left to right, and the value of the first expression that evaluates to a true value is returned. Any remaining expressions are not evaluated. If all expressions evaluate to `#f` or if there are no expressions, then `#f` is returned. + + (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) + # output-port-open? (output-port-open? port) @@ -582,6 +828,8 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # parameterize +*Syntax* + (parameterize (({param1} {value1}) ...) {body}) @@ -592,6 +840,8 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # quasiquote +*Syntax* + (quasiquote {qq template}) # quotient @@ -624,6 +874,8 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # receive +*Syntax* + (receive {formals} {expression} {body}) # record? @@ -736,6 +988,8 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # syntax-error +*Syntax* + (syntax-error {message} {args} ...) # truncate @@ -760,8 +1014,18 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # unless +*Syntax* + (unless {test} {expression1} {expression2} ...) +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 when expression is unspecified. + + (unless (= 1 1.0) + (display "1") + (display "2")) => unspecified and prints nothing + # utf8->string (utf8->string bytevector) @@ -832,8 +1096,18 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # when +*Syntax* + (when {test} {expression1} {expression2} ...) +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. + + (when (= 1 1.0) + (display "1") + (display "2")) => unspecified and prints 12 + # with-exception-handler (with-exception-handler handler thunk) diff --git a/docs/api/scheme/case-lambda.md b/docs/api/scheme/case-lambda.md index 6083fcd7..4bef77aa 100644 --- a/docs/api/scheme/case-lambda.md +++ b/docs/api/scheme/case-lambda.md @@ -13,8 +13,24 @@ For more information see the [R7RS Scheme Specification](../../r7rs.p # case-lambda +*Syntax* + (case-lambda {clause} ...) Syntax: Each `{clause}` is of the form `({formals} {body})`, where `{formals}` and `{body}` have the same syntax as in a lambda expression. Semantics: A `case-lambda` expression evaluates to a procedure that accepts a variable number of arguments and is lexically scoped in the same manner as a procedure resulting from a lambda expression. + +When the procedure is called, the first `{clause}` for which the arguments agree with `{formals}` is selected, where agreement is specified as for the `{formals}` of a lambda expression. The variables of `{formals}` are bound to fresh locations, the values of the arguments are stored in those locations, the `{body}` is evaluated in the extended environment, and the results of `{body}` are returned as the results of the procedure call. + +It is an error for the arguments not to agree with the `{formals}` of any `{clause}`. + + (define range + (case-lambda + ((e) (range 0 e)) + ((b e) (do ((r '() (cons e r)) + (e (- e 1) (- e 1))) + ((< e b) r))))) + + (range 3) => (0 1 2) + (range 3 5) => (3 4)