r7rs-small-texinfo

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

commit 2c3ff0be18f91abc8bcbab6274eb9ee97fc9cc84
parent 22c3d49b6fda769830ee182cd5cb6f7bddfad6a8
Author: Yuval Langer <yuvallangerontheroad@gmail.com>
Date:   Sat, 27 Jan 2024 18:35:14 +0200

Add more stuff.

Diffstat:
Mdoc/r7rs-small/r7rs-small.texinfo | 1835++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 1831 insertions(+), 4 deletions(-)

diff --git a/doc/r7rs-small/r7rs-small.texinfo b/doc/r7rs-small/r7rs-small.texinfo @@ -7319,52 +7319,1879 @@ modify this list. Here is an example of what features might return: @node Formal syntax and semantics @chapter Formal syntax and semantics + @node Formal syntax @section Formal syntax + +This chapter provides formal descriptions of what has already been described informally +in previous chapters of this report. + @node Lexical structure @subsection Lexical structure + +This section provides a formal syntax for Scheme written in an extended BNF. + +All spaces in the grammar are for legibility. Case is not significant except in the definitions +of <letter>, <character name> and <mnemonic escape>; for example, #x1A and #X1a are +equivalent, but foo and Foo and #\space and #\Space are distinct. <empty> stands for the +empty string. + +The following extensions to BNF are used to make the description more concise: <thing>* +means zero or more occurrences of <thing>; and <thing>+ means at least one <thing>. + @node External representations @subsection External representations + +This section describes how individual tokens(identifiers, numbers, etc.) are formed from +sequences of characters. The following sections describe how expressions and programs +are formed from sequences of tokens. + +<Intertoken space> can occur on either side of any token, but not within a token. + +Identifiers that do not begin with a vertical line are terminated by a <delimiter> or by the +end of the input. So are dot, numbers, characters, and booleans. Identifiers that begin +with a vertical line are terminated by another vertical line. + +The following four characters from the ASCII repertoire are reserved for future +extensions to the language: [ ] { } + +In addition to the identifier characters of the ASCII repertoire specified below, Scheme +implementations may permit any additional repertoire of non-ASCII Unicode characters to +be employed in identifiers, provided that each such character has a Unicode general +category of Lu, Ll, Lt, Lm, Lo, Mn, Mc, Me, Nd, Nl, No, Pd, Pc, Po, Sc, Sm, Sk, So, or Co, or is +U+200C or U+200D (the zero-width non-joiner and joiner, respectively, which are needed +for correct spelling in Persian, Hindi, and other languages). However, it is an error for the +first character to have a general category of Nd, Mc, or Me. It is also an error to use a +non-Unicode character in symbols or identifiers. + +All Scheme implementations must permit the escape sequence \x<hexdigits>; to appear in +Scheme identifiers that are enclosed in vertical lines. If the character with the given +Unicode scalar value is supported by the implementation, identifiers containing such a +sequence are equivalent to identifiers containing the corresponding character. + +<token> ⟶<identifier> ∣<boolean> ∣<number> ∣<character> ∣<string> +∣( ∣) ∣#( ∣#u8( ∣' ∣` ∣, ∣,@ ∣. +<delimiter> ⟶<whitespace> ∣<vertical line> +∣( ∣) ∣" ∣; +<intraline whitespace> ⟶<space or tab> +<whitespace> ⟶<intraline whitespace> ∣<line ending> +<vertical line> ⟶| +<line ending> ⟶<newline> ∣<return> <newline> +∣<return> +<comment> ⟶; ⟨all subsequent characters up to a +​ ​line ending⟩ ∣<nested comment> +∣#; <intertoken space> <datum> +<nested comment> ⟶#| <comment text> +<comment cont>* |# +<comment text> ⟶⟨character sequence not containing +​ ​#| or |#⟩ +<comment cont> ⟶<nested comment> <comment text> +<directive> ⟶#!fold-case ∣#!no-fold-case Note that it is ungrammatical to follow a +<directive> with anything but a <delimiter> or the end of file. + +<atmosphere> ⟶<whitespace> ∣<comment> ∣<directive> +<intertoken space> ⟶<atmosphere>* + +Note that +i, -i and <infnan> below are exceptions to the <peculiar identifier> rule; they are +parsed as numbers, not identifiers. + +<identifier> ⟶<initial> <subsequent>* +∣<vertical line> <symbol element>* <vertical line> +∣<peculiar identifier> +<initial> ⟶<letter> ∣<special initial> +<letter> ⟶a ∣b ∣c ∣... ∣z +∣A ∣B ∣C ∣... ∣Z +<special initial> ⟶! ∣$ ∣% ∣& ∣* ∣/ ∣: ∣< ∣= +∣> ∣? ∣@ ∣^ ∣_ ∣~ +<subsequent> ⟶<initial> ∣<digit> +∣<special subsequent> +<digit> ⟶0 ∣1 ∣2 ∣3 ∣4 ∣5 ∣6 ∣7 ∣8 ∣9 +<hex digit> ⟶<digit> ∣a ∣b ∣c ∣d ∣e ∣f +<explicit sign> ⟶+ ∣- +<special subsequent> ⟶<explicit sign> ∣. ∣@ +<inline hex escape> ⟶\x<hex scalar value>; +<hex scalar value> ⟶<hex digit>+ +<mnemonic escape> ⟶\a ∣\b ∣\t ∣\n ∣\r +<peculiar identifier> ⟶<explicit sign> +∣<explicit sign> <sign subsequent> <subsequent>* +∣<explicit sign> . <dot subsequent> <subsequent>* +∣. <dot subsequent> <subsequent>* +<dot subsequent> ⟶<sign subsequent> ∣. +<sign subsequent> ⟶<initial> ∣<explicit sign> ∣@ +<symbol element> ⟶ <any character other than <vertical line> or \> +∣<inline hex escape> ∣<mnemonic escape> ∣\| +<boolean> ⟶#t ∣#f ∣#true ∣#false + +<character> ⟶#\ <any character> +∣#\ <character name> +∣#\x<hex scalar value> +<character name> ⟶alarm ∣backspace ∣delete +∣escape ∣newline ∣null ∣return ∣space ∣tab + +<string> ⟶" <string element>* " +<string element> ⟶<any character other than " or \> +∣<mnemonic escape> ∣\" ∣\\ ∣\| +∣\<intraline whitespace>*<line ending> + <intraline whitespace>* +∣<inline hex escape> +<bytevector> ⟶#u8(<byte>*) +<byte> ⟶<any exact integer between 0 and 255> + +<number> ⟶<num 2> ∣<num 8> +∣<num 10> ∣<num 16> +The following rules for <num R>, <complex R>, <real R>, <ureal R>, <uinteger R>, and +<prefix R> are implicitly replicated for R = 2, 8, 10, and 16. There are no rules for <decimal +2>, <decimal 8>, and <decimal 16>, which means that numbers containing decimal points +or exponents are always in decimal radix. Although not shown below, all alphabetic +characters used in the grammar of numbers can appear in either upper or lower case. +<num R> ⟶<prefix R> <complex R> +<complex R> ⟶<real R> ∣<real R> @ <real R> +∣<real R> + <ureal R> i ∣<real R> - <ureal R> i +∣<real R> + i ∣<real R> - i ∣<real R> <infnan> i +∣+ <ureal R> i ∣- <ureal R> i +∣<infnan> i ∣+ i ∣- i +<real R> ⟶<sign> <ureal R> +∣<infnan> +<ureal R> ⟶<uinteger R> +∣<uinteger R> / <uinteger R> +∣<decimal R> +<decimal 10> ⟶<uinteger 10> <suffix> +∣. <digit 10>+ <suffix> +∣<digit 10>+ . <digit 10>* <suffix> +<uinteger R> ⟶<digit R>+ +<prefix R> ⟶<radix R> <exactness> +∣<exactness> <radix R> +<infnan> ⟶+inf.0 ∣-inf.0 ∣+nan.0 ∣-nan.0 +<suffix> ⟶<empty> +∣<exponent marker> <sign> <digit 10>+ +<exponent marker> ⟶e +<sign> ⟶<empty> ∣+ ∣- +<exactness> ⟶<empty> ∣#i∣#e<radix 2> ⟶#b<radix 8> ⟶#o<radix 10> ⟶<empty> ∣#d +<radix 16> ⟶#x<digit 2> ⟶0 ∣1 +<digit 8> ⟶0 ∣1 ∣2 ∣3 ∣4 ∣5 ∣6 ∣7 +<digit 10> ⟶<digit> +<digit 16> ⟶<digit 10> ∣a ∣b ∣c ∣d ∣e ∣f + @node Expressions @subsection Expressions + +<Datum> is what the read procedure (section 6.13.2) successfully parses. Note that any +string that parses as an <expression> will also parse as a <datum>. + +<datum> ⟶<simple datum> ∣<compound datum> +∣<label> = <datum> ∣<label> # +<simple datum> ⟶<boolean> ∣<number> +∣<character> ∣<string> ∣<symbol> ∣<bytevector> +<symbol> ⟶<identifier> +<compound datum> ⟶<list> ∣<vector> ∣<abbreviation> +<list> ⟶(<datum>*) ∣(<datum>+ .​ ​<datum>) +<abbreviation> ⟶<abbrev prefix> <datum> +<abbrev prefix> ⟶' ∣` ∣, ∣,@ +<vector> ⟶#(<datum>*) +<label> ⟶# <uinteger 10> + @node Quasiquotations @subsection Quasiquotations + +The definitions in this and the following subsections assume that all the syntax keywords +defined in this report have been properly imported from their libraries, and that none of +them have been redefined or shadowed. + +<expression> ⟶<identifier> +∣<literal> +∣<procedure call> +∣<lambda expression> +∣<conditional> +∣<assignment> +∣<derived expression> +∣<macro use> +∣<macro block> +∣<includer> +<literal> ⟶<quotation> ∣<self-evaluating> +<self-evaluating> ⟶<boolean> ∣<number> ∣<vector> +∣<character> ∣<string> ∣<bytevector> +<quotation> ⟶'<datum> ∣(quote <datum>) +<procedure call> ⟶(<operator> <operand>*) +<operator> ⟶<expression> +<operand> ⟶<expression> +<lambda expression> ⟶(lambda <formals> <body>) +<formals> ⟶(<identifier>*) ∣<identifier> +∣(<identifier>+ .​ ​<identifier>) +<body> ⟶<definition>* <sequence> +<sequence> ⟶<command>* <expression> +<command> ⟶<expression> +<conditional> ⟶(if <test> <consequent> <alternate>) +<test> ⟶<expression> +<consequent> ⟶<expression> +<alternate> ⟶<expression> ∣<empty> +<assignment> ⟶(set! <identifier> <expression>) +<derived expression> ⟶ (cond <cond clause>+) +∣(cond <cond clause>* (else <sequence>)) +∣(case <expression> + <case clause>+) +∣(case <expression> + <case clause>* + (else <sequence>)) +∣(case <expression> + <case clause>* + (else => <recipient>)) +∣(and <test>*) +∣(or <test>*) +∣(when <test> <sequence>) +∣(unless <test> <sequence>) +∣(let (<binding spec>*) <body>) +∣(let <identifier> (<binding spec>*) <body>) +∣(let* (<binding spec>*) <body>) +∣(letrec (<binding spec>*) <body>) +∣(letrec* (<binding spec>*) <body>) +∣(let-values (<mv binding spec>*) <body>) +∣(let*-values (<mv binding spec>*) <body>) +∣(begin <sequence>) +∣(do (<iteration spec>*) + (<test> <do result>) + <command>*) +∣(delay <expression>) +∣(delay-force <expression>) +∣(parameterize ((<expression> <expression>)*) + <body>) +∣(guard (<identifier> <cond clause>*) <body>) +∣<quasiquotation> +∣(case-lambda <case-lambda clause>*) +<cond clause> ⟶(<test> <sequence>) +∣(<test>) +∣(<test> => <recipient>) +<recipient> ⟶<expression> +<case clause> ⟶((<datum>*) <sequence>) +∣((<datum>*) => <recipient>) +<binding spec> ⟶(<identifier> <expression>) +<mv binding spec> ⟶(<formals> <expression>) +<iteration spec> ⟶(<identifier> <init> <step>) +∣(<identifier> <init>) +<case-lambda clause> ⟶(<formals> <body>) +<init> ⟶<expression> +<step> ⟶<expression> +<do result> ⟶<sequence> ∣<empty> +<macro use> ⟶(<keyword> <datum>*) +<keyword> ⟶<identifier> +<macro block> ⟶ (let-syntax (<syntax spec>*) <body>) +∣(letrec-syntax (<syntax spec>*) <body>) +<syntax spec> ⟶(<keyword> <transformer spec>) +<includer> ⟶ ∣(include <string>+) +∣(include-ci <string>+) + @node Transformers @subsection Transformers + +The following grammar for quasiquote expressions is not context-free. It is presented as +a recipe for generating an infinite number of production rules. Imagine a copy of the +following rules for D = 1, 2, 3, …, where D is the nesting depth. + +<quasiquotation> ⟶<quasiquotation 1> +<qq template 0> ⟶<expression> +<quasiquotation D> ⟶`<qq template D> +∣(quasiquote <qq template D>) +<qq template D> ⟶<simple datum> +∣<list qq template D> +∣<vector qq template D> +∣<unquotation D> +<list qq template D> ⟶(<qq template or splice D>*) +∣(<qq template or splice D>+ .​ ​<qq template D>) +∣'<qq template D> +∣<quasiquotation D + 1> +<vector qq template D> ⟶#(<qq template or splice D>*) +<unquotation D> ⟶,<qq template D−1> +∣(unquote <qq template D−1>) +<qq template or splice D> ⟶<qq template D> +∣<splicing unquotation D> +<splicing unquotation D> ⟶,@<qq template D−1> +∣(unquote-splicing <qq template D−1>) In <quasiquotation>s, a <list qq template D> can +sometimes be confused with either an <unquotation D> or a <splicing unquotation D>. +The interpretation as an <unquotation> or <splicing unquotation D> takes precedence. + @node Programs and definitions @subsection Programs and definitions + + Note: Though this grammar does not say so, a top-level syntax-rules pattern must be + a list pattern, not a vector pattern or an identifier pattern. + +<transformer spec> ⟶ (syntax-rules (<identifier>*) <syntax rule>*) +∣(syntax-rules <identifier> (<identifier>*) + ​ ​​ ​<syntax rule>*) +<syntax rule> ⟶(<pattern> <template>) +<pattern> ⟶<pattern identifier> +∣<underscore> +∣(<pattern>*) +∣(<pattern>+ . <pattern>) +∣(<pattern>* <pattern> <ellipsis> <pattern>*) +∣(<pattern>* <pattern> <ellipsis> <pattern>* + ​ ​​ ​. <pattern>) +∣#(<pattern>*) +∣#(<pattern>* <pattern> <ellipsis> <pattern>*) +∣<pattern datum> +<pattern datum> ⟶<string> +∣<character> +∣<boolean> +∣<number> +∣<bytevector> +<template> ⟶<pattern identifier> +∣(<template element>*) +∣(<template element>+ .​ ​<template>) +∣#(<template element>*) +∣<template datum> +<template element> ⟶<template> +∣<template> <ellipsis> +<template datum> ⟶<pattern datum> +<pattern identifier> ⟶<any identifier except ...> +<ellipsis> ⟶<an identifier defaulting to ...> +<underscore> ⟶<the identifier _> + @node Libraries @subsection Libraries +<program> ⟶ <import declaration>+ +<command or definition>+ +<command or definition> ⟶<command> +∣<definition> +∣(begin <command or definition>+) +<definition> ⟶(define <identifier> <expression>) +∣(define (<identifier> <def formals>) <body>) +∣<syntax definition> +∣(define-values <formals> <body>) +∣(define-record-type <identifier> + ​ ​​ ​<constructor> <identifier> <field spec>*) +∣(begin <definition>*) +<def formals> ⟶<identifier>* +∣<identifier>* .​ ​<identifier> +<constructor> ⟶(<identifier> <field name>*) +<field spec> ⟶(<field name> <accessor>) +∣(<field name> <accessor> <mutator>) +<field name> ⟶<identifier> +<accessor> ⟶<identifier> +<mutator> ⟶<identifier> +<syntax definition> ⟶ (define-syntax <keyword> <transformer spec>) + @node Formal semantics @section Formal semantics + +This section provides a formal denotational semantics for the primitive expressions of +Scheme and selected built-in procedures. The concepts and notation used here are +described in [36]; the definition of dynamic-wind is taken from [39]. The notation is +summarized below: + +[r7rs-Z-G-1.png] + +The reason that expression continuations take sequences of values instead of single +values is to simplify the formal treatment of procedure calls and multiple return values. + +The boolean flag associated with pairs, vectors, and strings will be true for mutable +objects and false for immutable objects. + +The order of evaluation within a call is unspecified. We mimic that here by applying +arbitrary permutations permute and unpermute, which must be inverses, to the arguments +in a call before and after they are evaluated. This is not quite right since it suggests, +incorrectly, that the order of evaluation is constant throughout a program (for any given +number of arguments), but it is a closer approximation to the intended semantics than a +left-to-right evaluation would be. + +The storage allocator new is implementation-dependent, but it must obey the following +axiom: if new σ ∈ L, then σ (new σ ∣ L)↓2 = false. + +The definition of calK is omitted because an accurate definition of calK would complicate +the semantics without being very interesting. + +If P is a program in which all variables are defined before being referenced or assigned, +then the meaning of P is + + calE [ [ ((lambda (I*) ] ] + P’) + <undefined> + …) + +where I* is the sequence of variables defined in P, P′ is the sequence of expressions +obtained by replacing every definition in P by an assignment, <undefined> is an +expression that evaluates to undefined, and calE is the semantic function that assigns +meaning to expressions. + @node Abstract syntax @subsection Abstract syntax + +XXX: TeX! + @node Domain equations @subsection Domain equations + +XXX: TeX! + @node Semantic functions @subsection Semantic functions + +XXX: TeX! + @node Auxiliary functions @subsection Auxiliary functions + +XXX: TeX! + @node Derived expression types @section Derived expression types -@node A Standard Libraries -@chapter A Standard Libraries +This section gives syntax definitions for the derived expression types in terms of the +primitive expression types (literal, variable, call, lambda, if, and set!), except for +quasiquote. + +Conditional derived syntax types: + +(define-syntax cond + (syntax-rules (else =>) + ((cond (else result1 result2 ...)) + (begin result1 result2 ...)) + ((cond (test => result)) + (let ((temp test)) + (if temp (result temp)))) + ((cond (test => result) clause1 clause2 ...) + (let ((temp test)) + (if temp + (result temp) + (cond clause1 clause2 ...)))) + ((cond (test)) test) + ((cond (test) clause1 clause2 ...) + (let ((temp test)) + (if temp + temp + (cond clause1 clause2 ...)))) + ((cond (test result1 result2 ...)) + (if test (begin result1 result2 ...))) + ((cond (test result1 result2 ...) + clause1 clause2 ...) + (if test + (begin result1 result2 ...) + (cond clause1 clause2 ...))))) +(define-syntax case + (syntax-rules (else =>) + ((case (key ...) + clauses ...) + (let ((atom-key (key ...))) + (case atom-key clauses ...))) + ((case key + (else => result)) + (result key)) + ((case key + (else result1 result2 ...)) + (begin result1 result2 ...)) + ((case key + ((atoms ...) => result)) + (if (memv key '(atoms ...)) + (result key))) + ((case key + ((atoms ...) result1 result2 ...)) + (if (memv key '(atoms ...)) + (begin result1 result2 ...))) + ((case key + ((atoms ...) => result) + clause clauses ...) + (if (memv key '(atoms ...)) + (result key) + (case key clause clauses ...))) + ((case key + ((atoms ...) result1 result2 ...) + clause clauses ...) + (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) + ((or test) test) + ((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 ...))))) +Binding constructs: -@node B Standard Feature Identifiers -@chapter B Standard Feature Identifiers +(define-syntax let + (syntax-rules () + ((let ((name val) ...) body1 body2 ...) + ((lambda (name ...) body1 body2 ...) + val ...)) + ((let tag ((name val) ...) body1 body2 ...) + ((letrec ((tag (lambda (name ...) + body1 body2 ...))) + tag) + val ...)))) +(define-syntax let* + (syntax-rules () + ((let* () body1 body2 ...) + (let () body1 body2 ...)) + ((let* ((name1 val1) (name2 val2) ...) + body1 body2 ...) + (let ((name1 val1)) + (let* ((name2 val2) ...) + body1 body2 ...))))) +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. + +(define-syntax letrec + (syntax-rules () + ((letrec ((var1 init1) ...) body ...) + (letrec "generate_temp_names" + (var1 ...) + () + ((var1 init1) ...) + body ...)) + ((letrec "generate_temp_names" + () + (temp1 ...) + ((var1 init1) ...) + body ...) + (let ((var1 <undefined>) ...) + (let ((temp1 init1) ...) + (set! var1 temp1) + ... + body ...))) + ((letrec "generate_temp_names" + (x y ...) + (temp ...) + ((var1 init1) ...) + body ...) + (letrec "generate_temp_names" + (y ...) + (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 + (syntax-rules () + ((let-values (binding ...) body0 body1 ...) + (let-values "bind" + (binding ...) () (begin body0 body1 ...))) + + ((let-values "bind" () tmps body) + (let tmps body)) + + ((let-values "bind" ((b0 e0) + binding ...) tmps body) + (let-values "mktmp" b0 e0 () + (binding ...) tmps body)) + + ((let-values "mktmp" () e0 args + bindings tmps body) + (call-with-values + (lambda () e0) + (lambda args + (let-values "bind" + bindings tmps body)))) + + ((let-values "mktmp" (a . b) e0 (arg ...) + bindings (tmp ...) body) + (let-values "mktmp" b e0 (arg ... x) + bindings (tmp ... (a x)) body)) + + ((let-values "mktmp" a e0 (arg ...) + bindings (tmp ...) body) + (call-with-values + (lambda () e0) + (lambda (arg ... . x) + (let-values "bind" + bindings (tmp ... (a x)) body)))))) +(define-syntax let*-values + (syntax-rules () + ((let*-values () body0 body1 ...) + (let () body0 body1 ...)) + + ((let*-values (binding0 binding1 ...) + 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)))) + ((define-values (var) expr) + (define var expr)) + ((define-values (var0 var1 ... varn) expr) + (begin + (define var0 + (call-with-values (lambda () expr) + 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-values (var0 var1 ... . varn) expr) + (begin + (define var0 + (call-with-values (lambda () expr) + 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-values var expr) + (define var + (call-with-values (lambda () expr) + list))))) +(define-syntax begin + (syntax-rules () + ((begin exp ...) + ((lambda () exp ...))))) +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. +(define-syntax begin + (syntax-rules () + ((begin exp) + exp) + ((begin exp1 exp2 ...) + (call-with-values + (lambda () exp1) + (lambda args + (begin exp2 ...)))))) +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. + +(define-syntax do + (syntax-rules () + ((do ((var init step ...) ...) + (test expr ...) + command ...) + (letrec + ((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 + +(make-promise #f (lambda () <expression>)) as follows + +(define-syntax delay-force + (syntax-rules () + ((delay-force expression) + (make-promise #f (lambda () expression))))) and we define the expression + +(delay <expression>) to have the same meaning as: + +(delay-force (make-promise #t <expression>)) as follows + +(define-syntax delay + (syntax-rules () + ((delay expression) + (delay-force (make-promise #t expression))))) where make-promise is defined as +follows: + +(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: + +(define (force promise) + (if (promise-done? promise) + (promise-value promise) + (let ((promise* ((promise-value promise)))) + (unless (promise-done? promise) + (promise-update! promise* promise)) + (force promise)))) with the following promise accessors: + +(define promise-done? + (lambda (x) (car (car x)))) +(define promise-value + (lambda (x) (cdr (car x)))) +(define promise-update! + (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 +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>: + +(define (make-parameter init . o) + (let* ((converter + (if (pair? o) (car o) (lambda (x) x))) + (value (converter init))) + (lambda args + (cond + ((null? args) + value) + ((eq? (car args) <param-set!>) + (set! value (cadr args))) + ((eq? (car args) <param-convert>) + converter) + (else + (error "bad parameter syntax")))))) Then parameterize uses dynamic-wind to +dynamically rebind the associated value: + +(define-syntax parameterize + (syntax-rules () + ((parameterize ("step") + ((param value p old new) ...) + () + body) + (let ((p param) ...) + (let ((old (p)) ... + (new ((p <param-convert>) value)) ...) + (dynamic-wind + (lambda () (p <param-set!> new) ...) + (lambda () . body) + (lambda () (p <param-set!> old) ...))))) + ((parameterize ("step") + args + ((param value) . rest) + body) + (parameterize ("step") + ((param value p old new) . args) + rest + body)) + ((parameterize ((param value) ...) . body) + (parameterize ("step") + () + ((param value) ...) + body)))) +The following implementation of guard depends on an auxiliary macro, here called +guard-aux. + +(define-syntax guard + (syntax-rules () + ((guard (var clause ...) e1 e2 ...) + ((call/cc + (lambda (guard-k) + (with-exception-handler + (lambda (condition) + ((call/cc + (lambda (handler-k) + (guard-k + (lambda () + (let ((var condition)) + (guard-aux + (handler-k + (lambda () + (raise-continuable condition))) + clause ...)))))))) + (lambda () + (call-with-values + (lambda () e1 e2 ...) + (lambda args + (guard-k + (lambda () + (apply values args))))))))))))) + +(define-syntax guard-aux + (syntax-rules (else =>) + ((guard-aux reraise (else result1 result2 ...)) + (begin result1 result2 ...)) + ((guard-aux reraise (test => result)) + (let ((temp test)) + (if temp + (result temp) + reraise))) + ((guard-aux reraise (test => result) + clause1 clause2 ...) + (let ((temp test)) + (if temp + (result temp) + (guard-aux reraise clause1 clause2 ...)))) + ((guard-aux reraise (test)) + (or test reraise)) + ((guard-aux reraise (test) clause1 clause2 ...) + (let ((temp test)) + (if temp + temp + (guard-aux reraise clause1 clause2 ...)))) + ((guard-aux reraise (test result1 result2 ...)) + (if test + (begin result1 result2 ...) + reraise)) + ((guard-aux reraise + (test result1 result2 ...) + clause1 clause2 ...) + (if test + (begin result1 result2 ...) + (guard-aux reraise clause1 clause2 ...))))) +(define-syntax case-lambda + (syntax-rules () + ((case-lambda (params body0 ...) ...) + (lambda args + (let ((len (length args))) + (letrec-syntax + ((cl (syntax-rules ::: () + ((cl) + (error "no matching clause")) + ((cl ((p :::) . body) . rest) + (if (= len (length '(p :::))) + (apply (lambda (p :::) + . body) + args) + (cl . rest))) + ((cl ((p ::: . tail) . body) + . rest) + (if (>= len (length '(p :::))) + (apply + (lambda (p ::: . tail) + . body) + args) + (cl . rest)))))) + (cl (params body0 ...) ...))))))) + +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. + +(define-syntax cond-expand + ;; Extend this to mention all feature ids and libraries + (syntax-rules (and or not else r7rs library scheme base) + ((cond-expand) + (syntax-error "Unfulfilled cond-expand")) + ((cond-expand (else body ...)) + (begin body ...)) + ((cond-expand ((and) body ...) more-clauses ...) + (begin body ...)) + ((cond-expand ((and req1 req2 ...) body ...) + more-clauses ...) + (cond-expand + (req1 + (cond-expand + ((and req2 ...) body ...) + more-clauses ...)) + more-clauses ...)) + ((cond-expand ((or) body ...) more-clauses ...) + (cond-expand more-clauses ...)) + ((cond-expand ((or req1 req2 ...) body ...) + more-clauses ...) + (cond-expand + (req1 + (begin body ...)) + (else + (cond-expand + ((or req2 ...) body ...) + more-clauses ...)))) + ((cond-expand ((not req) body ...) + more-clauses ...) + (cond-expand + (req + (cond-expand more-clauses ...)) + (else body ...))) + ((cond-expand (r7rs body ...) + more-clauses ...) + (begin body ...)) + ;; Add clauses here for each + ;; supported feature identifier. + ;; Samples: + ;; ((cond-expand (exact-closed body ...) + ;; more-clauses ...) + ;; (begin body ...)) + ;; ((cond-expand (ieee-float body ...) + ;; more-clauses ...) + ;; (begin body ...)) + ((cond-expand ((library (scheme base)) + body ...) + more-clauses ...) + (begin body ...)) + ;; Add clauses here for each library + ((cond-expand (feature-id body ...) + more-clauses ...) + (cond-expand more-clauses ...)) + ((cond-expand ((library (name ...)) + body ...) + more-clauses ...) + (cond-expand more-clauses ...)))) + +@node Appendices +@chapter Appendices + +@node Appendix A Standard Libraries +@section Appendix A Standard Libraries + +This section lists the exports provided by the standard libraries. The libraries are factored +so as to separate features which might not be supported by all implementations, or which +might be expensive to load. + +The scheme library prefix is used for all standard libraries, and is reserved for use by +future standards. + +@node Base Library +@subsection Base Library + +The (scheme base) library exports many of the procedures and syntax bindings that are +traditionally associated with Scheme. The division between the base library and the other +standard libraries is based on use, not on construction. In particular, some facilities that +are typically implemented as primitives by a compiler or the run-time system rather than +in terms of other standard procedures or syntax are not part of the base library, but are +defined in separate libraries. By the same token, some exports of the base library are +implementable in terms of other exports. They are redundant in the strict sense of the +word, but they capture common patterns of usage, and are therefore provided as +convenient abbreviations. + + * + + - ... + / < + <= = + => > + >= _ + abs and + append apply + assoc assq + assv begin + binary-port?​ ​ boolean=? + boolean?​ ​ bytevector + bytevector-append bytevector-copy + bytevector-copy! bytevector-length + bytevector-u8-ref bytevector-u8-set! + bytevector?​ ​ caar + cadr + call-with-current-continuation + call-with-port call-with-values + call/cc car + case cdar + cddr cdr + ceiling char->integer + char-ready?​ ​ char<=? + char<?​ ​ char=? + char>=?​ ​ char>? + char?​ ​ close-input-port + close-output-port close-port + complex?​ ​ cond + cond-expand cons + current-error-port current-input-port + current-output-port define + define-record-type define-syntax + define-values denominator + do dynamic-wind + else eof-object + eof-object?​ ​ eq? + equal?​ ​ eqv? + error error-object-irritants + error-object-message error-object? + even?​ ​ exact + exact-integer-sqrt exact-integer? + exact?​ ​ expt + features file-error? + floor floor-quotient + floor-remainder floor/ + flush-output-port for-each + gcd get-output-bytevector + get-output-string guard + if include + include-ci inexact + inexact?​ ​ input-port-open? + input-port?​ ​ integer->char + integer?​ ​ lambda + lcm length + let let* + let*-values let-syntax + let-values letrec + letrec* letrec-syntax + list list->string + list->vector list-copy + list-ref list-set! + list-tail list? + make-bytevector make-list + make-parameter make-string + make-vector map + max member + memq memv + min modulo + negative?​ ​ newline + not null? + number->string number? + numerator odd? + open-input-bytevector open-input-string + open-output-bytevector open-output-string + or output-port-open? + output-port?​ ​ pair? + parameterize peek-char + peek-u8 port? + positive?​ ​ procedure? + quasiquote quote + quotient raise + raise-continuable rational? + rationalize read-bytevector + read-bytevector! read-char + read-error?​ ​ read-line + read-string read-u8 + real?​ ​ remainder + reverse round + set! set-car! + set-cdr! square + string string->list + string->number string->symbol + string->utf8 string->vector + string-append string-copy + string-copy! string-fill! + string-for-each string-length + string-map string-ref + string-set! string<=? + string<?​ ​ string=? + string>=?​ ​ string>? + string?​ ​ substring + symbol->string symbol=? + symbol?​ ​ syntax-error + syntax-rules textual-port? + truncate truncate-quotient + truncate-remainder truncate/ + u8-ready?​ ​ unless + unquote unquote-splicing + utf8->string values + vector vector->list + vector->string vector-append + vector-copy vector-copy! + vector-fill! vector-for-each + vector-length vector-map + vector-ref vector-set! + vector?​ ​ when + with-exception-handler write-bytevector + write-char write-string + write-u8 zero? + +@node Case-Lambda Library +@subsection Case-Lambda Library + +The (scheme case-lambda) library exports the case-lambda syntax. + + case-lambda +@node Char Library +@subsection Char Library + +The (scheme char) library provides the procedures for dealing with characters that involve +potentially large tables when supporting all of Unicode. + + char-alphabetic?​ ​ char-ci<=? + char-ci<?​ ​ char-ci=? + char-ci>=?​ ​ char-ci>? + char-downcase char-foldcase + char-lower-case?​ ​ char-numeric? + char-upcase char-upper-case? + char-whitespace?​ ​ digit-value + string-ci<=?​ ​ string-ci<? + string-ci=?​ ​ string-ci>=? + string-ci>?​ ​ string-downcase + string-foldcase string-upcase + +@node Complex Library +@subsection Complex Library + +The (scheme complex) library exports procedures which are typically only useful with +non-real numbers. + + angle imag-part + magnitude make-polar + make-rectangular real-part + +@node CxR Library +@subsection CxR Library + +The (scheme cxr) library exports twenty-four procedures which are the compositions of +from three to four car and cdr operations. For example caddar could be defined by + +(define caddar + (lambda (x) (car (cdr (cdr (car x)))))). The procedures car and cdr themselves and the four +two-level compositions are included in the base library. See section 6.4. + + caaaar caaadr + caaar caadar + caaddr caadr + cadaar cadadr + cadar caddar + cadddr caddr + cdaaar cdaadr + cdaar cdadar + cdaddr cdadr + cddaar cddadr + cddar cdddar + cddddr cdddr + +@node Eval Library +@subsection Eval Library + +The (scheme eval) library exports procedures for evaluating Scheme data as programs. + + environment eval +@node File Library +@subsection File Library + +The (scheme file) library provides procedures for accessing files. + + call-with-input-file call-with-output-file + delete-file file-exists? + open-binary-input-file open-binary-output-file + open-input-file open-output-file + with-input-from-file with-output-to-file + +@node Inexact Library +@subsection Inexact Library + +The (scheme inexact) library exports procedures which are typically only useful with +inexact values. + + acos asin + atan cos + exp finite? + infinite?​ ​ log + nan?​ ​ sin + sqrt tan +@node Lazy Library +@subsection Lazy Library + +The (scheme lazy) library exports procedures and syntax keywords for lazy evaluation. + + delay delay-force + force make-promise + promise? + +@node Load Library +@subsection Load Library + +The (scheme load) library exports procedures for loading Scheme expressions from files. + + load + +@node Process-Context Library +@subsection Process-Context Library + +The (scheme process-context) library exports procedures for accessing with the +program’s calling context. + + command-line emergency-exit + exit + get-environment-variable + get-environment-variables + +@node Read Library +@subsection Read Library + +The (scheme read) library provides procedures for reading Scheme objects. + + read + +@node Repl Library +@subsection Repl Library + +The (scheme repl) library exports the interaction-environment procedure. + + interaction-environment + +@node Time Library +@subsection Time Library + +The (scheme time) library provides access to time-related values. + + current-jiffy current-second + jiffies-per-second + +@node Write Library +@subsection Write Library + +The (scheme write) library provides procedures for writing Scheme objects. + + display write + write-shared write-simple + +@node R5RS Library +@subsection R5RS Library + +The (scheme r5rs) library provides the identifiers defined by R5RS, except that +transcript-on and transcript-off are not present. Note that the exact and inexact +procedures appear under their R5RS​ ​names inexact->exact and exact->inexact +respectively. However, if an implementation does not provide a particular library such as +the complex library, the corresponding identifiers will not appear in this library either. + + * + + - ... + / < + <= = + => > + >= _ + abs acos + and angle + append apply + asin assoc + assq assv + atan begin + boolean?​ ​ caaaar + caaadr caaar + caadar caaddr + caadr caar + cadaar cadadr + cadar caddar + cadddr caddr + cadr + call-with-current-continuation + call-with-input-file call-with-output-file + call-with-values car + case cdaaar + cdaadr cdaar + cdadar cdaddr + cdadr cdar + cddaar cddadr + cddar cdddar + cddddr cdddr + cddr cdr + ceiling char->integer + char-alphabetic?​ ​ char-ci<=? + char-ci<?​ ​ char-ci=? + char-ci>=?​ ​ char-ci>? + char-downcase char-lower-case? + char-numeric?​ ​ char-ready? + char-upcase char-upper-case? + char-whitespace?​ ​ char<=? + char<?​ ​ char=? + char>=?​ ​ char>? + char?​ ​ close-input-port + close-output-port complex? + cond cons + cos current-input-port + current-output-port define + define-syntax delay + denominator display + do dynamic-wind + else eof-object? + eq?​ ​ equal? + eqv?​ ​ eval + even?​ ​ exact->inexact + exact?​ ​ exp + expt floor + for-each force + gcd if + imag-part inexact->exact + inexact?​ ​ input-port? + integer->char integer? + interaction-environment lambda + lcm length + let let* + let-syntax letrec + letrec-syntax list + list->string list->vector + list-ref list-tail + list?​ ​ load + log magnitude + make-polar make-rectangular + make-string make-vector + map max + member memq + memv min + modulo negative? + newline not + null-environment null? + number->string number? + numerator odd? + open-input-file open-output-file + or output-port? + pair?​ ​ peek-char + positive?​ ​ procedure? + quasiquote quote + quotient rational? + rationalize read + read-char real-part + real?​ ​ remainder + reverse round + scheme-report-environment + set! set-car! + set-cdr! sin + sqrt string + string->list string->number + string->symbol string-append + string-ci<=?​ ​ string-ci<? + string-ci=?​ ​ string-ci>=? + string-ci>?​ ​ string-copy + string-fill! string-length + string-ref string-set! + string<=?​ ​ string<? + string=?​ ​ string>=? + string>?​ ​ string? + substring symbol->string + symbol?​ ​ syntax-rules + tan truncate + values vector + vector->list vector-fill! + vector-length vector-ref + vector-set! vector? + with-input-from-file with-output-to-file + write write-char + zero? + +@node Appendix B Standard Feature Identifiers +@section Appendix B Standard Feature Identifiers + +An implementation may provide any or all of the feature identifiers listed below for use by +cond-expand and features, but must not provide a feature identifier if it does not provide +the corresponding feature. + +r7rsAll R7RS​ ​Scheme implementations have this feature. + +exact-closedThe algebraic operations +, -, *, and expt where the second argument is a +non-negative integer produce exact values given exact inputs. + +exact-complexExact complex numbers are provided. + +ieee-floatInexact numbers are IEEE 754 binary floating point values. + +full-unicodeAll Unicode characters present in Unicode version 6.0 are supported as +Scheme characters. + +ratios/ with exact arguments produces an exact result when the divisor is nonzero. + +posixThis implementation is running on a POSIX system. + +windowsThis implementation is running on Windows. + +unix, darwin, gnu-linux, bsd, freebsd, solaris, ...Operating system flags (perhaps more +than one). + +i386, x86-64, ppc, sparc, jvm, clr, llvm, ...CPU architecture flags. + +ilp32, lp64, ilp64, ...C memory model flags. + +big-endian, little-endianByte order flags. + +<name>The name of this implementation. + +<name-version>The name and version of this implementation. @node Language changes @chapter Language changes +@node Incompatibilities with R5RS +@section Incompatibilities with R5RS + +This section enumerates the incompatibilities between this report and the “Revised5 +report” [20]. + +This list is not authoritative, but is believed to be correct and complete. + +* Case sensitivity is now the default in symbols and character names. This means that + code written under the assumption that symbols could be written FOO or Foo in some + contexts and foo in other contexts can either be changed, be marked with the new + #!fold-case directive, or be included in a library using the include-ci library declaration. + All standard identifiers are entirely in lower case. + +* The syntax-rules construct now recognizes _ (underscore) as a wildcard, which means it + cannot be used as a syntax variable. It can still be used as a literal. + +* The R5RS​ ​procedures exact->inexact and inexact->exact have been renamed to their + R6RS​ ​names, inexact and exact, respectively, as these names are shorter and more + correct. The former names are still available in the R5RS​ ​library. + +* The guarantee that string comparison (with string<? and the related predicates) is a + lexicographical extension of character comparison (with char<? and the related + predicates) has been removed. + +* Support for the # character in numeric literals is no longer required. + +* Support for the letters s, f, d, and l as exponent markers is no longer required. + +* Implementations of string->number are no longer permitted to return #f when the + argument contains an explicit radix prefix, and must be compatible with read and the + syntax of numbers in programs. + +* The procedures transcript-on and transcript-off have been removed. + +@node Other language changes since R5RS +@section Other language changes since R5RS + +This section enumerates the additional differences between this report and the “Revised5 +report” [20]. + +This list is not authoritative, but is believed to be correct and complete. + +* Various minor ambiguities and unclarities in R5RS​ ​have been cleaned up. + +* Libraries have been added as a new program structure to improve encapsulation and + sharing of code. Some existing and new identifiers have been factored out into + separate libraries. Libraries can be imported into other libraries or main programs, with + controlled exposure and renaming of identifiers. The contents of a library can be made + conditional on the features of the implementation on which it is to be used. There is an + R5RS​ ​compatibility library. + +* The expressions types include, include-ci, and cond-expand have been added to the + base library; they have the same semantics as the corresponding library declarations. + +* Exceptions can now be signaled explicitly with raise, raise-continuable or error, and can + be handled with with-exception-handler and the guard syntax. Any object can specify an + error condition; the implementation-defined conditions signaled by error have a + predicate to detect them and accessor functions to retrieve the arguments passed to + error. Conditions signaled by read and by file-related procedures also have predicates + to detect them. + +* New disjoint types supporting access to multiple fields can be generated with the + define-record-type of SRFI 9 [19] + +* Parameter objects can be created with make-parameter, and dynamically rebound with + parameterize. The procedures current-input-port and current-output-port are now + parameter objects, as is the newly introduced current-error-port. + +* Support for promises has been enhanced based on SRFI 45 [38]. + +* Bytevectors, vectors of exact integers in the range from 0 to 255 inclusive, have been + added as a new disjoint type. A subset of the vector procedures is provided. + Bytevectors can be converted to and from strings in accordance with the UTF-8 + character encoding. Bytevectors have a datum representation and evaluate to + themselves. + +* Vector constants evaluate to themselves. + +* The procedure read-line is provided to make line-oriented textual input simpler. + +* The procedure flush-output-port is provided to allow minimal control of output port + buffering. + +* Ports can now be designated as textual or binary ports, with new procedures for reading + and writing binary data. The new predicates input-port-open? and output-port-open? + return whether a port is open or closed. The new procedure close-port now closes a + port; if the port has both input and output sides, both are closed. + +* String ports have been added as a way to read and write characters to and from strings, + and bytevector ports to read and write bytes to and from bytevectors. + +* There are now I/O procedures specific to strings and bytevectors. + +* The write procedure now generates datum labels when applied to circular objects. The + new procedure write-simple never generates labels; write-shared generates labels for + all shared and circular structure. The display procedure must not loop on circular + objects. + +* The R6RS​ ​procedure eof-object has been added. Eof-objects are now required to be a + disjoint type. + +* Syntax definitions are now allowed wherever variable definitions are. + +* The syntax-rules construct now allows the ellipsis symbol to be specified explicitly + instead of the default ..., allows template escapes with an ellipsis-prefixed list, and + allows tail patterns to follow an ellipsis pattern. + +* The syntax-error syntax has been added as a way to signal immediate and more + informative errors when a macro is expanded. + +* The letrec* binding construct has been added, and internal define is specified in terms + of it. + +* Support for capturing multiple values has been enhanced with define-values, + let-values, and let*-values. Standard expression types which contain a sequence of + expressions now permit passing zero or more than one value to the continuations of + all non-final expressions of the sequence. + +* The case conditional now supports => syntax analogous to cond not only in regular + clauses but in the else clause as well. + +* To support dispatching on the number of arguments passed to a procedure, + case-lambda has been added in its own library. + +* The convenience conditionals when and unless have been added. + +* The behavior of eqv? on inexact numbers now conforms to the R6RS​ ​definition. + +* When applied to procedures, eq? and eqv? are permitted to return different answers. + +* The R6RS​ ​procedures boolean=? and symbol=? have been added. + +* Positive infinity, negative infinity, NaN, and negative inexact zero have been added to + the numeric tower as inexact values with the written representations +inf.0, -inf.0, + +nan.0, and -0.0 respectively. Support for them is not required. The representation - + nan.0 is synonymous with +nan.0. + +* The log procedure now accepts a second argument specifying the logarithm base. + +* The procedures map and for-each are now required to terminate on the shortest + argument list. + +* The procedures member and assoc now take an optional third argument specifying the + equality predicate to be used. + +* The numeric procedures finite?, infinite?, nan?, exact-integer?, square, and + exact-integer-sqrt have been added. + +* The - and / procedures and the character and string comparison predicates are now + required to support more than two arguments. + +* The forms #true and #false are now supported as well as #t and #f. + +* The procedures make-list, list-copy, list-set!, string-map, string-for-each, string->vector, + vector-append, vector-copy, vector-map, vector-for-each, vector->string, vector-copy!, + and string-copy! have been added to round out the sequence operations. + +* Some string and vector procedures support processing of part of a string or vector + using optional + + start and + + end arguments. + +* Some list procedures are now defined on circular lists. + +* Implementations may provide any subset of the full Unicode repertoire that includes + ASCII, but implementations must support any such subset in a way consistent with + Unicode. Various character and string procedures have been extended accordingly, and + case conversion procedures added for strings. String comparison is no longer required + to be consistent with character comparison, which is based solely on Unicode scalar + values. The new digit-value procedure has been added to obtain the numerical value of + a numeric character. + +* There are now two additional comment syntaxes: #; to skip the next datum, and #| ... |# + for nestable block comments. + +* Data prefixed with datum labels #<n>= can be referenced with #<n>#, allowing for + reading and writing of data with shared structure. + +* Strings and symbols now allow mnemonic and numeric escape sequences, and the list + of named characters has been extended. + +* The procedures file-exists?​ ​and delete-file are available in the (scheme file) library. + +* An interface to the system environment, command line, and process exit status is + available in the (scheme process-context) library. + +* Procedures for accessing time-related values are available in the (scheme time) library. + +* A less irregular set of integer division operators is provided with new and clearer + names. + +* The load procedure now accepts a second argument specifying the environment to + load into. + +* The call-with-current-continuation procedure now has the synonym call/cc. + +* The semantics of read-eval-print loops are now partly prescribed, requiring the + redefinition of procedures, but not syntax keywords, to have retroactive effect. + +* The formal semantics now handles dynamic-wind. + +@node Incompatibilities with R6RS +@section Incompatibilities with R6RS + +This section enumerates the incompatibilities between R7RS and the “Revised6 report” +[33] and its accompanying Standard Libraries document. + +This list is not authoritative, and is possibly incomplete. + +* R7RS​ ​libraries begin with the keyword define-library rather than library in order to + make them syntactically distinguishable from R6RS​ ​libraries. In R7RS​ ​terms, the body of + an R6RS​ ​library consists of a single export declaration followed by a single import + declaration, followed by commands and definitions. In R7RS, commands and definitions + are not permitted directly within the body: they have to be wrapped in a begin library + declaration. + +* There is no direct R6RS​ ​equivalent of the include, include-ci, + include-library-declarations, or cond-expand library declarations. On the other hand, + the R7RS​ ​library syntax does not support phase or version specifications. + +* The grouping of standardized identifiers into libraries is different from the R6RS + approach. In particular, procedures which are optional in R5RS either expressly or by + implication, have been removed from the base library. Only the base library itself is an + absolute requirement. + +* No form of identifier syntax is provided. + +* Internal syntax definitions are allowed, but uses of a syntax form cannot appear before + its definition; the even/odd example given in R6RS​ ​is not allowed. + +* The R6RS​ ​exception system was incorporated as-is, but the condition types have been + left unspecified. In particular, where R6RS​ ​requires a condition of a specified type to be + signaled, R7RS​ ​says only “it is an error”, leaving the question of signaling open. + +* Full Unicode support is not required. Normalization is not provided. Character + comparisons are defined by Unicode, but string comparisons are + implementation-dependent. Non-Unicode characters are permitted. + +* The full numeric tower is optional as in R5RS, but optional support for IEEE infinities, + NaN, and was adopted from R6RS. Most clarifications on numeric results were also + adopted, but the semantics of the R6RS​ ​procedures real?, rational?, and integer? were + not adopted. (Note that the R5RS/R7RS​ ​semantics are available in R6RS​ ​using + real-valued?, rational-valued?, and integer-valued?). The R6RS​ ​division operators div, + mod, div-and-mod, div0, mod0 and div0-and-mod0 are not provided. + +* When a result is unspecified, it is still required to be a single value. However, non-final + expressions in a body can return any number of values. + +* The semantics of map and for-each have been changed to use the SRFI 1 [30] early + termination behavior. Likewise, assoc and member take an optional equal? argument + as in SRFI 1, instead of the separate assp and memp procedures of R6RS. + +* The R6RS quasiquote clarifications have been adopted, with the exception of + multiple-argument unquote and unquote-splicing. + +* The R6RS method of specifying mantissa widths was not adopted. + +* String ports are compatible with SRFI 6 [7] rather than R6RS. + +* R6RS-style bytevectors are included, but only the unsigned byte (u8) procedures have + been provided. The lexical syntax uses #u8 for compatibility with SRFI 4 [13], rather than + the R6RS #vu8 style. + +* The utility macros when and unless are provided, but their result is left unspecified. + +* The remaining features of the Standard Libraries document were left to future + standardization efforts. + @node Additional material @chapter Additional material +The Scheme community website at http://schemers.org contains additional resources for +learning and programming, job and event postings, and Scheme user group information. + +A bibliography of Scheme-related research at http://library.readscheme.org links to +technical papers and theses related to the Scheme language, including both classic +papers and recent research. + +On-line Scheme discussions are held using IRC on the #scheme channel at +irc.freenode.net and on the Usenet discussion group comp.lang.scheme. + @node Example @chapter Example +The procedure integrate-system integrates the system + + yk⁄ = fk(y1, y2, …, yn), k = 1, + …, n + +of differential equations with the method of Runge-Kutta. + +The parameter system-derivative is a function that takes a system state (a vector of values +for the state variables y1, …, yn) and produces a system derivative (the values y1⁄, …, yn⁄). The +parameter initial-state provides an initial system state, and h is an initial guess for the +length of the integration step. + +The value returned by integrate-system is an infinite stream of system states. + +(define (integrate-system system-derivative + initial-state + h) + (let ((next (runge-kutta-4 system-derivative h))) + (letrec ((states + (cons initial-state + (delay (map-streams next + states))))) + states))) 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. + +(define (runge-kutta-4 f h) + (let ((*h (scale-vector h)) + (*2 (scale-vector 2)) + (*1/2 (scale-vector (/ 1 2))) + (*1/6 (scale-vector (/ 1 6)))) + (lambda (y) + ;; y is a system state + (let* ((k0 (*h (f y))) + (k1 (*h (f (add-vectors y (*1/2 k0))))) + (k2 (*h (f (add-vectors y (*1/2 k1))))) + (k3 (*h (f (add-vectors y k2))))) + (add-vectors y + (*1/6 (add-vectors k0 + (*2 k1) + (*2 k2) + k3))))))) + +(define (elementwise f) + (lambda vectors + (generate-vector + (vector-length (car vectors)) + (lambda (i) + (apply f + (map (lambda (v) (vector-ref v i)) + vectors)))))) + +(define (generate-vector size proc) + (let ((ans (make-vector size))) + (letrec ((loop + (lambda (i) + (cond ((= i size) ans) + (else + (vector-set! ans i (proc i)) + (loop (+ i 1))))))) + (loop 0)))) + +(define add-vectors (elementwise +)) + +(define (scale-vector s) + (elementwise (lambda (x) (* x s)))) 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). + +(define (map-streams f s) + (cons (f (head s)) + (delay (map-streams f (tail s))))) 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. + +(define head car) +(define (tail stream) + (force (cdr stream))) + +The following illustrates the use of integrate-system in integrating the system + + C dvC = −iL vC + − + dt R + + L diL = vC + + dt + +which models a damped oscillator. + +(define (damped-oscillator R L C) + (lambda (state) + (let ((Vc (vector-ref state 0)) + (Il (vector-ref state 1))) + (vector (- 0 (+ (/ Vc (* R C)) (/ Il C))) + (/ Vc L))))) + +(define the-states + (integrate-system + (damped-oscillator 10000 1000 .001) + '#(1 0) + .01)) + @node References @chapter References + [1] Harold Abelson and Gerald Jay Sussman with Julie Sussman. Structure and + Interpretation of Computer Programs, second edition. MIT Press, Cambridge, + 1996. + [2] Alan Bawden and Jonathan Rees. Syntactic closures. In Proceedings of the 1988 + ACM Symposium on Lisp and Functional Programming, pages 86–95. + [3] S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. + http://www.ietf.org/rfc/rfc2119.txt, 1997. + [4] Robert G. Burger and R. Kent Dybvig. Printing floating-point numbers quickly + and accurately. In Proceedings of the ACM SIGPLAN ’96 Conference on + Programming Language Design and Implementation, pages 108–116. + [5] William Clinger. How to read floating point numbers accurately. In Proceedings + of the ACM SIGPLAN ’90 Conference on Programming Language Design and + Implementation, pages 92–101. Proceedings published as SIGPLAN Notices 25 + (6), June 1990. + [6] William Clinger. Proper Tail Recursion and Space Efficiency. In Proceedings of + the 1998 ACM Conference on Programming Language Design and Implementation, + June 1998. + [7] William Clinger. SRFI 6: Basic String Ports. http://srfi.schemers.org/srfi-6/, + 1999. + [8] William Clinger, editor. The revised revised report on Scheme, or an + uncommon Lisp. MIT Artificial Intelligence Memo 848, August 1985. Also + published as Computer Science Department Technical Report 174, Indiana + University, June 1985. + [9] William Clinger and Jonathan Rees. Macros that work. In Proceedings of the + 1991 ACM Conference on Principles of Programming Languages, pages 155–162. + [10] William Clinger and Jonathan Rees, editors. The revised4 report on the + algorithmic language Scheme. In ACM Lisp Pointers 4(3), pages 1–55, 1991. + [11] Mark Davis. Unicode Standard Annex #44, Unicode Character Database. + http://unicode.org/reports/tr44/, 2010. + [12] R. Kent Dybvig, Robert Hieb, and Carl Bruggeman. Syntactic abstraction in + Scheme. Lisp and Symbolic Computation 5(4):295–326, 1993. + [13] Marc Feeley. SRFI 4: Homogeneous Numeric Vector Datatypes. + http://srfi.schemers.org/srfi-4/, 1999. + [14] Carol Fessenden, William Clinger, Daniel P. Friedman, and Christopher + Haynes. Scheme 311 version 4 reference manual. Indiana University + Computer Science Technical Report 137, February 1983. Superseded by [15]. + [15] D. Friedman, C. Haynes, E. Kohlbecker, and M. Wand. Scheme 84 interim + reference manual. Indiana University Computer Science Technical Report 153, + January 1985. + [16] Martin Gardner. Mathematical Games: The fantastic combinations of John + Conway’s new solitaire game “Life.” In Scientific American, 223:120–123, October + 1970. + [17] IEEE Standard 754-2008. IEEE Standard for Floating-Point Arithmetic. IEEE, New + York, 2008. + [18] IEEE Standard 1178-1990. IEEE Standard for the Scheme Programming Language. + IEEE, New York, 1991. + [19] Richard Kelsey. SRFI 9: Defining Record Types. http://srfi.schemers.org/srfi-9/, + 1999. + [20] Richard Kelsey, William Clinger, and Jonathan Rees, editors. The revised5 + report on the algorithmic language Scheme. Higher-Order and Symbolic + Computation, 11(1):7-105, 1998. + [21] Eugene E. Kohlbecker Jr. Syntactic Extensions in the Programming Language Lisp. + PhD thesis, Indiana University, August 1986. + [22] Eugene E. Kohlbecker Jr., Daniel P. Friedman, Matthias Felleisen, and Bruce + Duba. Hygienic macro expansion. In Proceedings of the 1986 ACM Conference on + Lisp and Functional Programming, pages 151–161. + [23] John McCarthy. Recursive Functions of Symbolic Expressions and Their + Computation by Machine, Part I. Communications of the ACM 3(4):184–195, April + 1960. + [24] MIT Department of Electrical Engineering and Computer Science. Scheme + manual, seventh edition. September 1984. + [25] Peter Naur et al. Revised report on the algorithmic language Algol 60. + Communications of the ACM 6(1):1–17, January 1963. + [26] Paul Penfield, Jr. Principal values and branch cuts in complex APL. In APL ’81 + Conference Proceedings, pages 248–256. ACM SIGAPL, San Francisco, September + 1981. Proceedings published as APL Quote Quad 12(1), ACM, September 1981. + [27] Jonathan A. Rees and Norman I. Adams IV. T: A dialect of Lisp or, lambda: The + ultimate software tool. In Conference Record of the 1982 ACM Symposium on Lisp + and Functional Programming, pages 114–122. + [28] Jonathan A. Rees, Norman I. Adams IV, and James R. Meehan. The T manual, + fourth edition. Yale University Computer Science Department, January 1984. + [29] Jonathan Rees and William Clinger, editors. The revised3 report on the + algorithmic language Scheme. In ACM SIGPLAN Notices 21(12), pages 37–79, + December 1986. + [30] Olin Shivers. SRFI 1: List Library. http://srfi.schemers.org/srfi-1/, 1999. + [31] Guy Lewis Steele Jr. and Gerald Jay Sussman. The revised report on Scheme, a + dialect of Lisp. MIT Artificial Intelligence Memo 452, January 1978. + [32] Guy Lewis Steele Jr. Rabbit: a compiler for Scheme. MIT Artificial Intelligence + Laboratory Technical Report 474, May 1978. + [33] Michael Sperber, R. Kent Dybvig, Mathew Flatt, and Anton van Straaten, + editors. The revised6 report on the algorithmic language Scheme. Cambridge + University Press, 2010. + [34] Guy Lewis Steele Jr. Common Lisp: The Language, second edition. Digital Press, + Burlington MA, 1990. + [35] Gerald Jay Sussman and Guy Lewis Steele Jr. Scheme: an interpreter for + extended lambda calculus. MIT Artificial Intelligence Memo 349, December + 1975. + [36] Joseph E. Stoy. Denotational Semantics: The Scott-Strachey Approach to + Programming Language Theory. MIT Press, Cambridge, 1977. + [37] Texas Instruments, Inc. TI Scheme Language Reference Manual. Preliminary + version 1.0, November 1985. + [38] Andre van Tonder. SRFI 45: Primitives for Expressing Iterative Lazy + Algorithms. http://srfi.schemers.org/srfi-45/, 2002. + [39] Martin Gasbichler, Eric Knauel, Michael Sperber and Richard Kelsey. How to + Add Threads to a Sequential Language Without Getting Tangled Up. + Proceedings of the Fourth Workshop on Scheme and Functional Programming, + November 2003. + [40] International Earth Rotation Service. Historical table of TAI-UTC offsets. + http://maia.usno.navy.mil/ser7/tai-utc.dat + @c Alphabetic index of definitions of concepts, keywords, and procedures + +@bye