From 32e91015944dc36313bd5662390d93e33967047e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 11 Jun 2007 07:19:42 +0000 Subject: [PATCH] guide and reference work; change opt-lambda to use lambda/kw and hack in keyword support for documentation purposes, along with define-opt svn: r6572 --- collects/mzlib/etc.ss | 126 +++++--- collects/mzlib/for.ss | 2 + collects/scribble/eval.ss | 12 +- collects/scribble/latex-render.ss | 2 +- collects/scribble/manual.ss | 73 ++++- collects/scribble/scheme.ss | 8 +- collects/scribblings/guide/apply.scrbl | 91 +++++- collects/scribblings/guide/byte-strings.scrbl | 4 +- collects/scribblings/guide/char-strings.scrbl | 4 +- collects/scribblings/guide/chars.scrbl | 4 +- .../scribblings/guide/define-struct.scrbl | 30 +- collects/scribblings/guide/define.scrbl | 113 ++++++- collects/scribblings/guide/forms.scrbl | 72 ++++- collects/scribblings/guide/guide-utils.ss | 11 +- collects/scribblings/guide/guide.scrbl | 15 +- collects/scribblings/guide/hash-tables.scrbl | 4 +- collects/scribblings/guide/keywords.scrbl | 4 +- collects/scribblings/guide/lambda.scrbl | 209 ++++++++----- collects/scribblings/guide/lists.scrbl | 2 +- collects/scribblings/guide/numbers.scrbl | 2 +- collects/scribblings/guide/paths.scrbl | 4 +- .../scribblings/guide/simple-syntax.scrbl | 16 +- collects/scribblings/guide/symbols.scrbl | 2 +- collects/scribblings/guide/truth.scrbl | 2 +- collects/scribblings/guide/vectors.scrbl | 2 +- collects/scribblings/reference/bytes.scrbl | 2 +- collects/scribblings/reference/chars.scrbl | 11 + collects/scribblings/reference/data.scrbl | 18 +- collects/scribblings/reference/derived.scrbl | 209 +------------ collects/scribblings/reference/for.scrbl | 281 ++++++++++++++++++ collects/scribblings/reference/macros.scrbl | 4 + collects/scribblings/reference/numbers.scrbl | 15 +- collects/scribblings/reference/read.scrbl | 16 +- .../scribblings/reference/reference.scrbl | 16 + collects/scribblings/reference/strings.scrbl | 6 +- collects/scribblings/reference/syntax.scrbl | 9 +- doc/release-notes/mred/HISTORY | 6 + doc/release-notes/mzscheme/HISTORY | 2 +- 38 files changed, 971 insertions(+), 438 deletions(-) create mode 100644 collects/scribblings/reference/for.scrbl diff --git a/collects/mzlib/etc.ss b/collects/mzlib/etc.ss index ecb85297e2..3fd0ec0c48 100644 --- a/collects/mzlib/etc.ss +++ b/collects/mzlib/etc.ss @@ -1,7 +1,8 @@ (module etc mzscheme - (require (lib "main-collects.ss" "setup")) + (require (lib "main-collects.ss" "setup") + "kw.ss") (require-for-syntax (lib "kerncase.ss" "syntax") (lib "stx.ss" "syntax") @@ -23,6 +24,7 @@ loop-until opt-lambda + define-opt local recur @@ -129,52 +131,82 @@ (eq? x y)) (define-syntax (opt-lambda stx) - (with-syntax ([name (or (syntax-local-infer-name stx) - (quote-syntax opt-lambda-proc))]) - (syntax-case stx () - [(_ args body1 body ...) - (let ([clauses (let loop ([pre-args null] - [args (syntax args)] - [needs-default? #f]) - (syntax-case args () - [id - (identifier? (syntax id)) - (with-syntax ([(pre-arg ...) pre-args]) - (syntax ([(pre-arg ... . id) - body1 body ...])))] - [() - (with-syntax ([(pre-arg ...) pre-args]) - (syntax ([(pre-arg ...) - body1 body ...])))] - [(id . rest) - (identifier? (syntax id)) - (begin - (when needs-default? - (raise-syntax-error - #f "default value missing" stx (syntax id))) - (loop (append pre-args (list (syntax id))) - (syntax rest) - #f))] - [([id default] . rest) - (identifier? (syntax id)) - (with-syntax ([rest (loop (append pre-args (list (syntax id))) - (syntax rest) - #t)] - [(pre-arg ...) pre-args]) - (syntax ([(pre-arg ...) (name pre-arg ... default)] - . rest)))] - [(bad . rest) - (raise-syntax-error - #f - "not an identifier or identifier with default" - stx - (syntax bad))] - [else - (raise-syntax-error - #f "bad identifier sequence" stx (syntax args))]))]) - (with-syntax ([clauses clauses]) - (syntax/loc stx - (letrec ([name (case-lambda . clauses)]) name))))]))) + (syntax-case stx () + [(_ args body1 body ...) + (with-syntax ([((plain ...) (opt ...) (kw ...) need-kw rest) + (let loop ([args (syntax args)] + [needs-default? #f]) + (syntax-case args () + [id + (identifier? (syntax id)) + #'(() () () () (#:body id))] + [() + #'(() () () () ())] + [(id . rest) + (identifier? (syntax id)) + (begin + (when needs-default? + (raise-syntax-error + #f "default value missing" stx (syntax id))) + (with-syntax ([(plain opts kws need-kw rest) (loop #'rest #f)]) + #'((id . plain) opts kws need-kw rest)))] + [([id default] . rest) + (identifier? (syntax id)) + (with-syntax ([(plain opts kws need-kw rest) (loop #'rest #t)]) + #'(plain ([id default] . opts) kws need-kw rest))] + [(kw id . rest) + (and (identifier? #'id) + (keyword? (syntax-e #'kw))) + (with-syntax ([(plain opts kws need-kw rest) (loop #'rest needs-default?)]) + #'(plain opts ([id kw #f] . kws) (kw . need-kw) rest))] + [(kw [id default] . rest) + (and (identifier? #'id) + (keyword? (syntax-e #'kw))) + (with-syntax ([(plain opts kws need-kw rest) (loop #'rest needs-default?)]) + #'(plain opts ([id kw default] . kws) need-kw rest))] + [(bad . rest) + (raise-syntax-error + #f + "not an identifier or identifier with default" + stx + (syntax bad))] + [else + (raise-syntax-error + #f "bad identifier sequence" stx (syntax args))]))]) + (let ([kw-proc (syntax/loc stx + (lambda/kw [plain ... #:optional opt ... #:key kw ... . rest] body1 body ...))]) + (if (null? (syntax-e #'(kw ...))) + kw-proc + (with-syntax ([name (or (syntax-local-infer-name stx) + (quote-syntax opt-lambda-proc))] + [kw-proc kw-proc] + [len (length (syntax->list #'(plain ...)))]) + (syntax/loc stx + (let ([name kw-proc]) + (lambda all-args + (apply name (sort-kws len 'need-kw all-args)))))))))])) + + (define-syntax define-opt + (syntax-rules () + [(_ (id . args) body1 body ...) + (define id (opt-lambda args body1 body ...))] + [(_ . rest) (define . rest)])) + + (define (sort-kws len need-kw l) + (for-each (lambda (kw) + (unless (memq kw l) + (error "missing required argument for" kw))) + need-kw) + (let loop ([len len][l l][kws null]) + (cond + [(null? l) (append kws l)] + [(zero? len) (append kws l)] + [(and (keyword? (car l)) + (pair? (cdr l))) + (loop len (cddr l) (list* (car l) + (cadr l) + kws))] + [else (cons (car l) (loop (sub1 len) (cdr l) kws))]))) (define-syntax (local stx) (syntax-case stx () diff --git a/collects/mzlib/for.ss b/collects/mzlib/for.ss index 3396b7d7c0..ec9a8f6e4f 100644 --- a/collects/mzlib/for.ss +++ b/collects/mzlib/for.ss @@ -8,6 +8,8 @@ for/or for*/or for/first for*/first for/last for*/last + + for/fold/derived for*/fold/derived (rename *in-range in-range) (rename *in-naturals in-naturals) diff --git a/collects/scribble/eval.ss b/collects/scribble/eval.ss index 470945a8c9..530827561e 100644 --- a/collects/scribble/eval.ss +++ b/collects/scribble/eval.ss @@ -210,9 +210,9 @@ [(_ (eval:alts a b)) (schemeinput* a)] [(_ e) (schemeinput e)])) - (define (defspace p) - (make-flow (list p - (make-paragraph null)))) + (define-code schemeblock+line (to-paragraph/prefix (hspace 2) + (hspace 2) + (list " "))) (define-syntax (schemedefinput* stx) (syntax-case stx (eval-example-string define define-struct) @@ -220,13 +220,13 @@ #'(schemeinput* (eval-example-string s))] [(_ (define . rest)) (syntax-case stx () - [(_ e) #'(defspace (schemeblock e))])] + [(_ e) #'(schemeblock+line e)])] [(_ (define-struct . rest)) (syntax-case stx () - [(_ e) #'(defspace (schemeblock e))])] + [(_ e) #'(schemeblock+line e)])] [(_ (code:line (define . rest) . rest2)) (syntax-case stx () - [(_ e) #'(defspace (schemeblock e))])] + [(_ e) #'(schemeblock+line e)])] [(_ e) #'(schemeinput e)])) (define-syntax titled-interaction diff --git a/collects/scribble/latex-render.ss b/collects/scribble/latex-render.ss index bd1d8297a2..011732a89d 100644 --- a/collects/scribble/latex-render.ss +++ b/collects/scribble/latex-render.ss @@ -75,7 +75,7 @@ (pair? number)) (printf "\\~a~a{" (case (length number) - [(0 1) "section"] + [(0 1) "newpage\n\n\\section"] [(2) "subsection"] [(3) "subsubsection"] [else "subsubsection*"]) diff --git a/collects/scribble/manual.ss b/collects/scribble/manual.ss index 1baa026072..96670c923d 100644 --- a/collects/scribble/manual.ss +++ b/collects/scribble/manual.ss @@ -150,7 +150,8 @@ ;; ---------------------------------------- (provide defproc defproc* defstruct defthing defform defform* defform/subs defform*/subs defform/none - specform specsubform specsubform/inline + specform specform/subs + specsubform specspecsubform specsubform/inline schemegrammar var svar void-const undefined-const) @@ -250,15 +251,30 @@ (define-syntax specsubform (syntax-rules () [(_ spec desc ...) - (*specsubform 'spec #f (lambda () (schemeblock0 spec)) (lambda () (list desc ...)))])) + (*specsubform 'spec #f (lambda () (schemeblock0 spec)) null null (lambda () (list desc ...)))])) + (define-syntax specspecsubform + (syntax-rules () + [(_ spec desc ...) + (make-blockquote "leftindent" (list (specsubform spec desc ...)))])) (define-syntax specform (syntax-rules () [(_ spec desc ...) - (*specsubform 'spec #t (lambda () (schemeblock0 spec)) (lambda () (list desc ...)))])) + (*specsubform 'spec #t (lambda () (schemeblock0 spec)) null null (lambda () (list desc ...)))])) + (define-syntax specform/subs + (syntax-rules () + [(_ spec ([non-term-id non-term-form ...] ...) desc ...) + (*specsubform 'spec #t + (lambda () (schemeblock0 spec)) + '((non-term-id non-term-form ...) ...) + (list (list (lambda () (scheme non-term-id)) + (lambda () (schemeblock0 non-term-form)) + ...) + ...) + (lambda () (list desc ...)))])) (define-syntax specsubform/inline (syntax-rules () [(_ spec desc ...) - (*specsubform 'spec #f #f (lambda () (list desc ...)))])) + (*specsubform 'spec #f #f null null (lambda () (list desc ...)))])) (define-syntax defthing (syntax-rules () [(_ id result desc ...) @@ -523,9 +539,10 @@ sub-procs)))) (content-thunk))))) - (define (*specsubform form has-kw? form-thunk content-thunk) + (define (*specsubform form has-kw? form-thunk subs sub-procs content-thunk) (parameterize ([current-variable-list - (append (let loop ([form (if has-kw? (cdr form) form)]) + (append (let loop ([form (cons (if has-kw? (cdr form) form) + subs)]) (cond [(symbol? form) (if (meta-symbol? form) null @@ -539,12 +556,20 @@ (cons (make-table 'boxed - (list (list - (make-flow - (list - (if form-thunk - (form-thunk) - (make-paragraph (list (to-element form))))))))) + (cons + (list + (make-flow + (list + (if form-thunk + (form-thunk) + (make-paragraph (list (to-element form))))))) + (apply + append + (map (lambda (sub) + (list (list (make-flow (list (make-paragraph (list (tt 'nbsp)))))) + (list (make-flow (list (apply *schemerawgrammar + (map (lambda (f) (f)) sub))))))) + sub-procs)))) (flow-paragraphs (decode-flow (content-thunk))))))) (define (*schemerawgrammar nonterm clause1 . clauses) @@ -643,5 +668,29 @@ [else (list i)]))) c))))) + ;; ---------------------------------------- + + (provide cite) + + (define/kw (cite #:key key title author location date) + "[...]" + #; + (make-bibliography-element + #f + (list "[...]") + key + (list (string-append + (content->string (list author)) + ", " + (content->string (list title)))) + (list (make-element #f (list author + ", " + title + ", " + date + ". " + location + "."))))) + ;; ---------------------------------------- ) diff --git a/collects/scribble/scheme.ss b/collects/scribble/scheme.ss index 96546c6339..1acb0bf1f7 100644 --- a/collects/scribble/scheme.ss +++ b/collects/scribble/scheme.ss @@ -369,7 +369,6 @@ (string? (syntax-e c)) (bytes? (syntax-e c)) (char? (syntax-e c)) - (keyword? (syntax-e c)) (boolean? (syntax-e c))) value-color] [(identifier? c) @@ -389,7 +388,12 @@ (set! dest-col 0) (hash-table-put! next-col-map init-col dest-col) ((loop (lambda () (set! src-col init-col) (set! dest-col 0)) 0) c) - (out suffix #f) + (if (list? suffix) + (map (lambda (sfx) + (finish-line!) + (out sfx #f)) + suffix) + (out suffix #f)) (unless (null? content) (finish-line!)) (if multi-line? diff --git a/collects/scribblings/guide/apply.scrbl b/collects/scribblings/guide/apply.scrbl index fb185148b5..9ae0cf335f 100644 --- a/collects/scribblings/guide/apply.scrbl +++ b/collects/scribblings/guide/apply.scrbl @@ -12,19 +12,19 @@ An expression of the form ] is a procedure application when @scheme[_proc-expr] is not an -identifier that is bound as a transformer. The @scheme[...] in this -syntactic sketch means ``zero or more repetitions of the preceding -element.'' Specifically, it means zero or more @scheme[_arg-expr]s. +identifier that is bound as a transformer. + +@section{Evaluation Order and Arity} A procedure application is evaluated by first evaluating the @scheme[_proc-expr] and all @scheme[_arg-expr]s in order (left to right). Then, if @scheme[_proc-expr] produced a procedure that accepts as many arguments as supplied @scheme[_arg-expr]s, the procedure is -aplied. Otherwise, an exception is raised. +applied. Otherwise, an exception is raised. @examples[ (cons 1 null) -((lambda (x y z) (+ x y z)) 1 2 3) +(+ 1 2 3) (cons 1 2 3) (1 2 3) ] @@ -32,19 +32,80 @@ aplied. Otherwise, an exception is raised. Some procedures, such as @scheme[cons], accept a fixed number of arguments. Some procedures, such as @scheme[list], accept any number of arguments. Some procedures accept a range of argument counts; for -example @scheme[substring] accepts either two or three arguments. +example @scheme[substring] accepts either two or three arguments. A +procedure's @idefterm{arity} is the number(s) of arguments that it +accepts. + +@;------------------------------------------------------------------------ +@section{Keyword Arguments} Some procedures accept @defterm{keyword arguments} in addition to -by-position arguments. To supply a keyword argument, include a keyword -followed by the addociated argument value. The order of keyword -arguments does not matter, nor does their position relative to -non-keyword arguments (as long as they follow the procedure -expression); keyword arguments are recognized by an applied procedure -using only the associated keyword, not the order. +by-position arguments. For that case, an @scheme[_arg] can be an +@scheme[_arg-keyword _arg-expr] sequence instead of just a +@scheme[_arg-expr]: -@examples[ -(need-an-example 1 #:arg 2) -(need-an-example #:arg 2 1) +@specform/subs[ +(_proc-expr _arg ...) +([arg arg-expr + (code:line arg-keyword arg-expr)]) ] +For example, + +@schemeblock[(go "super.ss" #:mode 'fast)] + +calls the procedure bound to @scheme[go] with @scheme["super.ss"] as a +by-position argument, and with @scheme['fast] as an argument associated +with the @scheme[#:mode] keyword. Thus, a keyword is implicitly paired +with the expression that follows it. Since a keyword by itself is not +an expression, then + +@schemeblock[(go "super.ss" #:mode #:fast)] + +is a syntax error---because @scheme[#:fast] is not an expression. + +The order of keyword @scheme[_arg]s determines the order in which +@scheme[_arg-expr]s are evaluated, but a procedure accepts (or +declines) keyword arguments independent of their position in the +argument list. That is, keyword arguments are recognized by an applied +procedure using only the associated keyword. The above call to +@scheme[go] can be equivalently written + +@schemeblock[(go #:mode #:fast "super.ss")] + @refdetails["mz:application"]{procedure applications} + +@;------------------------------------------------------------------------ +@section[#:tag "guide:apply"]{The @scheme[apply] Procedure} + +The syntax for procedure applications supports any number of +arguments, but a specific application expression always specifies a +fixed number of arguments. As a result, a procedure that takes a list +of arguments cannot directly apply a procedure like @scheme[+] to all +of the items in the list: + +@def+int[ +(define (avg lst) (code:comment #, @elem{doesn't work...}) + (/ (+ lst) (length lst))) +(avg '(1 2 3)) +] + +@def+int[ +(define (avg lst) (code:comment #, @elem{doesn't always work...}) + (/ (+ (list-ref lst 0) (list-ref lst 1) (list-ref lst 2)) + (length lst))) +(avg '(1 2 3)) +(avg '(1 2)) +] + +The @scheme[apply] procedure offers a way around this restriction, It +takes another procedure a @italic{list} arguments, and it applies the +procedure to the arguments: + +@def+int[ +(define (avg lst) + (/ (apply + lst) (length lst))) +(avg '(1 2 3)) +(avg '(1 2)) +(avg '(1 2 3 4)) +] diff --git a/collects/scribblings/guide/byte-strings.scrbl b/collects/scribblings/guide/byte-strings.scrbl index 9a4a280df7..89bd6a0990 100644 --- a/collects/scribblings/guide/byte-strings.scrbl +++ b/collects/scribblings/guide/byte-strings.scrbl @@ -23,7 +23,7 @@ prints like the ASCII decoding of the byte string, but prefixed with a @litchar{#}. Unprintable ASCII characters or non-ASCII bytes in the byte string are written with octal notation. -@refdetails["mz:parse-string"]{the syntax of byte strings} +@refdetails/gory["mz:parse-string"]{the syntax of byte strings} @examples[ #"Apple" @@ -37,7 +37,7 @@ b ] The @scheme[display] form of a byte string writes its raw bytes to the -current output port (see @secref["output"]). Technically, +current output port (see @secref["guide:i/o"]). Technically, @scheme[display] of a normal (i.e,. character) string prints the UTF-8 encoding of the string to the current output port, since output is ultimately defined in terms of bytes; @scheme[display] of a byte diff --git a/collects/scribblings/guide/char-strings.scrbl b/collects/scribblings/guide/char-strings.scrbl index 7f32cb9603..ed00e518ca 100644 --- a/collects/scribblings/guide/char-strings.scrbl +++ b/collects/scribblings/guide/char-strings.scrbl @@ -15,10 +15,10 @@ to three octal digits, and hexadimal escapes with @litchar["\\u"] (up to four digits). Unprintable characters in a string normally shown with @litchar["\\u"] when the string is printed. -@refdetails["mz:parse-string"]{the syntax of strings} +@refdetails/gory["mz:parse-string"]{the syntax of strings} The @scheme[display] procedure directly writes the characters of a -string to the current output port (see @secref["output"]), in contrast +string to the current output port (see @secref["guide:i/o"]), in contrast to the string-constant syntax used to print a string result. @examples[ diff --git a/collects/scribblings/guide/chars.scrbl b/collects/scribblings/guide/chars.scrbl index 4b8c59ce94..96300ba532 100644 --- a/collects/scribblings/guide/chars.scrbl +++ b/collects/scribblings/guide/chars.scrbl @@ -26,7 +26,7 @@ number. A few characters are printed specially; for example, the space and linefeed characters print as @scheme[#\space] and @scheme[#\newline], respectively. -@refdetails["mz:parse-character"]{the syntax of characters} +@refdetails/gory["mz:parse-character"]{the syntax of characters} @examples[ (integer->char 65) @@ -38,7 +38,7 @@ and linefeed characters print as @scheme[#\space] and ] The @scheme[display] procedure directly writes a character to the -current output port (see @secref["output"]), in contrast to the +current output port (see @secref["guide:i/o"]), in contrast to the character-constant syntax used to print a character result. @examples[ diff --git a/collects/scribblings/guide/define-struct.scrbl b/collects/scribblings/guide/define-struct.scrbl index db1c306ef6..de1c7f3243 100644 --- a/collects/scribblings/guide/define-struct.scrbl +++ b/collects/scribblings/guide/define-struct.scrbl @@ -17,9 +17,9 @@ objects to @secref["classes"]. To a first approximation, the syntax of @scheme[define-struct] is -@schemeblock[ -(define-struct _struct-id (_field-id ...)) -] +@specform[ +(define-struct struct-id (field-id ...)) +]{} Such a definition binds @scheme[_struct-id], but only to static information about the structure type that cannot be used directly: @@ -71,13 +71,13 @@ are built from @scheme[_struct-id] and the @scheme[_field-id]s: } A @scheme[define-struct] form places no constraints on the kinds of -values that can appears for fields in an instance of the structure +values that can appear for fields in an instance of the structure type. For example, @scheme[(make-posn "apple" #f)] produces an instance of @scheme[posn], even though @scheme["apple"] and -@scheme[#f] are not valid co-ordinates for the obvious uses of +@scheme[#f] are not valid coordinates for the obvious uses of @scheme[posn] instances. Enforcing constraints on field values, such as requiring them to be numbers, is the job of a contract, as -discussed later in @secref["contracts"]. +discussed later in @secref["guide:contracts"]. @; ------------------------------------------------------------ @section{Structure Subtypes} @@ -86,8 +86,8 @@ An extended form of @scheme[defin-struct] can be used to define a @defterm{structure subtype}, which is a structure type that extends an existing structure type: -@schemeblock[ -(define-struct (_struct-id _super-id) (_field-id ...)) +@specform[ +(define-struct (struct-id super-id) (field-id ...)) ] The @scheme[_super-id] must be a structure type name bound by @@ -133,13 +133,19 @@ To make a structure type @defterm{transparent}, use the field-name sequence: @def+int[ -(define-struct posn (x y) - #f) +'(define-struct posn (x y) + #:inspector #f) (make-posn 1 2) ] An instance of a transparent structure type prints like a vector, and it shows the content of the structure's fields. A transparent -structure type allows allows reflective operations like -@scheme[struct?] and @scheme[struct-info] to be used on its +structure type also allows reflective operations, like +@scheme[struct?] and @scheme[struct-info], to be used on its instances (see @secref["reflection"]). + +Structure types are opaque by default, because opaque structure +instances provide more encapsulation guarantees. That is, a library +can use an opaque structure to encapsulate data, and clients of the +library cannot manipulate the data in the structure except as allowed +by the library. diff --git a/collects/scribblings/guide/define.scrbl b/collects/scribblings/guide/define.scrbl index 131da60c5a..f7d3952d8e 100644 --- a/collects/scribblings/guide/define.scrbl +++ b/collects/scribblings/guide/define.scrbl @@ -3,8 +3,117 @@ @require[(lib "eval.ss" "scribble")] @require["guide-utils.ss"] +@interaction-eval[(require (rename (lib "etc.ss") define define-opt))] + @title{Definitions: @scheme[define] and @scheme[define-values]} -A definition can have the form +A basic definition has the form -@specform[(define _id _expr)] +@specform[(define id expr)]{} + +in which case @scheme[_id] is bound to the result of +@scheme[_expr]. + +@defexamples[ +(define salutation (list-ref '("Hi" "Hello") (random 2))) +salutation +] + +@;------------------------------------------------------------------------ +@section{Procedure Shorthand} + +The @scheme[define] form also supports a shorthand for procedure +definitions: + +@specform[(define (id arg ...) body ...+)]{} + +which is a shorthand for + +@schemeblock[ +(define id (lambda (arg ...) _body ...+)) +] + +@defexamples[ +(define (greet name) + (string-append salutation ", " name)) +(greet "John") +] + +@def+int[ +(define (greet first [surname "Smith"] #:hi [hi salutation]) + (string-append hi ", " first " " surname)) +(greet "John") +(greet "John" #:hi "Hey") +(greet "John" "Doe") +] + +The procedure shorthand via @scheme[define] also supports a final +argument to collect extra arguments in a list: + +@specform[(define (id arg ... . rest-id) expr)]{} + +which is a shorthand + +@schemeblock[ +(define id (lambda (id arg ... . rest-id) body-expr ...+)) +] + +@defexamples[ +(define (avg . l) + (/ (apply + l) (length l))) +(avg 1 2 3) +] + +@;------------------------------------------------------------------------ +@section[#:tag "guide:multiple-values"]{Multiple Values} + +A Scheme expression normally produces a single result, but some +expressions can produce multiple results. For example, +@scheme[quotient] and @scheme[remainder] each produce a single value, +but @scheme[quotient/remainder] produces the same two values at once: + +@interaction[ +(quotient 13 3) +(remainder 13 3) +(quotient/remainder 13 3) +] + +As shown abpve, the REPL prints each result value on its own line. + +Multiple-valued procedures can be implemented in terms of the +@scheme[values] procedure, which takes any number of values and +returns them as the results: + +@interaction[ +(values 1 2 3) +] +@def+int[ +(define (split-name name) + (let ([m (regexp-match #rx"^([^ ]*) (.*)$" name)]) + (values (list-ref m 1) (list-ref m 2)))) +(split-name "Adam Smith") +] + +The @scheme[define-values] form binds multiple identifiers at once to +multiple results produced from a single expression: + +@specform[(define-values (id ...) expr)]{} + +The number of results produced by the @scheme[_expr] must match the +number of @scheme[_id]s. + +@defexamples[ +(define-values (given surname) (split-name "Adam Smith")) +given +surname +] + +A @scheme[define] form (that is not a procedure shorthand) is +equivalent to a @scheme[define-values] form with a single @scheme[id]. + +@;------------------------------------------------------------------------ +@section[#:tag "guide:intdefs"]{Internal Definitions} + +When the grammar for a syntactic form specified @scheme[_body], then +the corresponding position in an instance of the grammar can be either +a definition or an expression. diff --git a/collects/scribblings/guide/forms.scrbl b/collects/scribblings/guide/forms.scrbl index 0464b8f8e9..5308c82729 100644 --- a/collects/scribblings/guide/forms.scrbl +++ b/collects/scribblings/guide/forms.scrbl @@ -6,12 +6,78 @@ @title[#:tag "scheme-forms" #:style 'toc]{Expressions and Definitions} The @secref["to-scheme"] chapter introduced some of Scheme's syntactic -forms: definitions, procedure applications, conditionals, procedures, -local binding, and some iteration forms. This section provides a more -complete coverage of the basic Scheme syntactic forms. +forms: definitions, procedure applications, conditionals, and so +on. This section provides more details on those forms, plus a few +additional basic forms. @local-table-of-contents[] +@section[#:tag "guide:syntax-notation"]{Notation} + +This chapter (and the rest of the documentation) uses a slightly +different notation than the character-based grammars of the +@secref["to-scheme"] chapter. The grammar for a use of a syntactic +form @schemekeywordfont{something} is shown like this: + +@specform[(#,(schemekeywordfont "something") [id ...+] an-expr ...)] + +The italicized meta-variables in this specification, such as +@scheme[_id] and @scheme[_an-expr], use the syntax of Scheme +identifiers, so @scheme[_an-expr] is one meta-variable. A naming +convention implicitly defines the meaning of many meta-variables: + +@itemize{ + + @item{A meta-variable that ends in @scheme[_id] stands for an + identifier, such as @schemeidfont{x} or + @schemeidfont{my-favorite-martian}.} + + @item{A meta-identifier that ends in @scheme[_keyword] stands + for a keyword, such as @scheme[#:tag].} + + @item{A meta-identifier that ends with @scheme[_expr] stands for any + sub-form, and it will be parsed as an expression.} + + @item{A meta-identifier that ends with @scheme[_body] stands for any + sub-form; it will be parsed as either a local definition or an + expression. A @scheme[_body] can parse as a definition only if + it is not preceded by any expression, and the last + @scheme[_body] must be an expression.} + +} + +Square brackets in the grammar indicate a parenthesized sequence of +forms, where square brackets are normally used (by convention). That +is square brackets @italic{do not} mean optional parts of the +syntactic form. + +A @scheme[...] indicates zero or more repetitions of the preceding +form, and @scheme[...+] indicates one or more repetitions of the +preceding datum. Otherwise, non-italicized identifiers stand form +themselves. + +Based on the above grammar, then, here are a few legal uses of +@schemekeywordfont{something}: + +@schemeblock[ +(#,(schemekeywordfont "something") [x]) +(#,(schemekeywordfont "something") [x] (+ 1 2)) +(#,(schemekeywordfont "something") [x my-favorite-martian x] (+ 1 2) #f) +] + +Some syntactic forms refer to meta-variables that are not implicitly +defined and not previously defined. Such meta-variables are defined +using a BNF-like format for alternatives: + +@specform/subs[(#,(schemekeywordfont "something-else") [thing ...+] an-expr ...) + ([thing thing-id + thing-keyword])] + +The above example says that, within a @schemekeywordfont{something-else} +form, a @scheme[_thing] is either an identifier or a keyword. + +@;------------------------------------------------------------------------ + @include-section["binding.scrbl"] @include-section["apply.scrbl"] @include-section["lambda.scrbl"] diff --git a/collects/scribblings/guide/guide-utils.ss b/collects/scribblings/guide/guide-utils.ss index 0001e01356..4e346e163e 100644 --- a/collects/scribblings/guide/guide-utils.ss +++ b/collects/scribblings/guide/guide-utils.ss @@ -7,6 +7,7 @@ (provide Quick MzScheme HtDP tool refdetails + refdetails/gory refsecref) (define Quick @@ -21,13 +22,19 @@ (define (tool name . desc) (apply item (bold name) ", " desc)) - (define/kw (refdetails tag #:body s) + (define/kw (refdetails* tag what #:body s) (apply margin-note - (decode-content (append (list "For more on ") + (decode-content (append (list "For " what " on ") s (list ", see " (refsecref tag) "."))))) + (define/kw (refdetails tag #:body s) + (apply refdetails* tag "more" s)) + + (define/kw (refdetails/gory tag #:body s) + (apply refdetails* tag "gory details" s)) + (define (refsecref s) (make-element #f (list (secref s) " in " MzScheme)))) diff --git a/collects/scribblings/guide/guide.scrbl b/collects/scribblings/guide/guide.scrbl index 78ef77e18e..fdfe088281 100644 --- a/collects/scribblings/guide/guide.scrbl +++ b/collects/scribblings/guide/guide.scrbl @@ -24,14 +24,14 @@ precise details to @|MzScheme| and other reference manuals. @include-section["data.scrbl"] -@include-section["define-struct.scrbl"] - @include-section["forms.scrbl"] +@include-section["define-struct.scrbl"] + @include-section["module-basics.scrbl"] @; ---------------------------------------------------------------------- -@section[#:tag "contracts"]{Contracts} +@section[#:tag "guide:contracts"]{Contracts} In the reference manual, the documentation for each procedure describes the acceptable arguments and the result of the procedure @@ -54,7 +54,11 @@ using @idefterm{contracts}. @; ---------------------------------------------------------------------- -@section[#:tag "i/o"]{I/O and Networking} +@section[#:tag "guide:i/o"]{Input and Output} + + +@; ---------------------------------------------------------------------- +@section[#:tag "guide:networking"]{Networking} @; ---------------------------------------------------------------------- @@ -88,6 +92,9 @@ using @idefterm{contracts}. @; ---------------------------------------------------------------------- @section[#:tag "memory-management"]{Memory Management} +@subsection[#:tag "guide:weakboxes"]{Weak Boxes} + +@subsection[#:tag "guide:ephemerons"]{Ephemerons} @; ---------------------------------------------------------------------- @section[#:tag "performance"]{Performance} diff --git a/collects/scribblings/guide/hash-tables.scrbl b/collects/scribblings/guide/hash-tables.scrbl index 9dd52763e1..2f8b6514e8 100644 --- a/collects/scribblings/guide/hash-tables.scrbl +++ b/collects/scribblings/guide/hash-tables.scrbl @@ -33,7 +33,7 @@ key--value pair. Literal hash tables are immutable. (hash-table-get ht "apple") ] -@refdetails["mz:parse-hashtable"]{the syntax of hash table literals} +@refdetails/gory["mz:parse-hashtable"]{the syntax of hash table literals} A hash table can optionally retain its keys @defterm{weakly}, so each mapping is retained only so long as the key is retained elsewhere. @@ -49,7 +49,7 @@ Beware that even a weak hash table retains its values strongly, as long as the corresponding key is accessible. This creates a catch-22 dependency when a value refers back to its key, so that the mapping is retained permanently. To break the cycle, map the key to an -@seclink["ephemerons"]{ephemeron} that pair the value with its key (in +@seclink["guide:ephemerons"]{ephemeron} that pair the value with its key (in addition to the implicit pairing of the hash table). @examples[ diff --git a/collects/scribblings/guide/keywords.scrbl b/collects/scribblings/guide/keywords.scrbl index 64471f7fd8..0f7f1849a2 100644 --- a/collects/scribblings/guide/keywords.scrbl +++ b/collects/scribblings/guide/keywords.scrbl @@ -5,10 +5,10 @@ @title[#:tag "keywords"]{Keywords} -A @defterm{keyword} is similar to a symbol (see @secref["symbols"]), +A @defterm{keyword} is similar to a symbol (see @secref["guide:symbols"]), but its printed form is prefixed with @litchar{#:}. -@refdetails["mz:parse-keyword"]{the syntax of keywords} +@refdetails/gory["mz:parse-keyword"]{the syntax of keywords} @examples[ (string->keyword "apple") diff --git a/collects/scribblings/guide/lambda.scrbl b/collects/scribblings/guide/lambda.scrbl index 11d805eeeb..afe2dba2c7 100644 --- a/collects/scribblings/guide/lambda.scrbl +++ b/collects/scribblings/guide/lambda.scrbl @@ -3,6 +3,8 @@ @require[(lib "eval.ss" "scribble")] @require["guide-utils.ss"] +@interaction-eval[(require (rename (lib "etc.ss") lambda opt-lambda))] + @title[#:tag "guide:lambda"]{Procedures: @scheme[lambda] and @scheme[case-lambda]} A @scheme[lambda] expression creates a procedure. In the simplest @@ -10,13 +12,9 @@ case, a @scheme[lambda] expression has the form @specform[ (lambda (arg-id ...) - body-expr ...+) + body ...+) ] -The @scheme[...+] in this syntactic sketch means ``one or more -repetitions of the preceeding element.'' Specifically, it means one or -more @scheme[_body-expr]s. - A @scheme[lambda] form with @math{n} @scheme[_arg-id]s accepts @math{n} arguments: @@ -29,11 +27,14 @@ A @scheme[lambda] form with @math{n} @scheme[_arg-id]s accepts 1) ] +@;------------------------------------------------------------------------ +@section{Rest Arguments} + A @scheme[lambda] expression can also have the form @specform[ (lambda rest-id - body-expr ...+) + body ...+) ] That is, a @scheme[lambda] expression can have a single @@ -49,108 +50,160 @@ into a list bound to @scheme[_rest-id]. 1 2 3) ] -Combining thes two styles, a @scheme[lambda] expression can have the -form +Procedures of this form often use @scheme[apply] to call another +procedure that accepts any number of arguments. + +@margin-note{See @secref["guide:apply"] for more information on +@scheme[apply].} + +@defexamples[ +(define max-mag + (lambda nums + (apply max (map magnitude nums)))) + +(max 1 -2 0) +(max-mag 1 -2 0) +] + +Generalizing the fixed-arity and any-arity style, a @scheme[lambda] +expression can have the form @specform[ (lambda (arg-id ...+ . rest-id) - body-expr ...+) + body ...+) ] The result is a procedure that requires at least as many arguments as @scheme[_arg-id]s, and also accepts any number of additional arguments. -@examples[ -((lambda (a b . x) (cons (/ a b) x)) - 1 2 3 4) -((lambda (a b . x) (cons (/ a b) x)) - 1 2) -((lambda (a b . x) (cons (/ a b) x)) - 1) +@defexamples[ +(define max-mag + (lambda (num . nums) + (apply max (map magnitude (cons num nums))))) + +(max-mag 1 -2 0) +(max-mag) ] -Support for optional and keyword arguments lead to even more -possibilities: +A @scheme[_rest-id] variable is sometimes called a @defterm{rest +argument}, because it accepts the ``rest'' of the procedure arguments. -@itemize{ +@;------------------------------------------------------------------------ +@section{Optional Arguments} - @item{Instead of just an @scheme[_arg-id], an form argument can be - @scheme[[_arg-id _default-expr]], which means that the argument - is optional. When the argument is not supplied, - @scheme[_default-expr] produces the default value. The - @scheme[_default-expr] can refer to any preceding - @scheme[_arg-id], and every following @scheme[_arg-id] must - have a default as well. +Instead of just an identifier, an argument (other than a rest +argument) in a @scheme[lambda] form can be specified with an +identifier and a default value: - @examples[ - ((lambda (x [y 5]) (list x y)) - 1 2) - ((lambda (x [y 5]) (list x y)) - 1) - ((lambda (x [y (+ x 1)]) (list x y)) - 1) - (lambda ([x 5] y) (list x y)) - ]} +@specform/subs[ +(lambda (arg ...+ . rest-id) + body ...+) +([arg arg-id + [arg-id default-expr]]) +]{} - @item{Instead of just an @scheme[_arg-id], an form argument can be - @scheme[(code:line _keyword _arg-id)], which indicates a - by-keyword argument instead of a by-position argument. The - position of the keyword--identifier pair in the argument list - does not matter for matching with arguments in an application, - because it will be matched to an argument value by keyword - insteda of by position. +A argument of the form @scheme[[arg-id default-expr]] is +optional. When the argument is not supplied in an application, +@scheme[_default-expr] produces the default value. The +@scheme[_default-expr] can refer to any preceding @scheme[_arg-id], +and every following @scheme[_arg-id] must have a default as well. - @examples[ - ((lambda (x #:second y) (list x y)) - 1 #:second 2) - ((lambda (x #:second y) (list x y)) - #:second 2 1) - ((lambda (#:second y x) (list x y)) - 1 #:second 2) - ((lambda (x #:second y) (list x y)) - 1 2) - ((lambda (x #:second y) (list x y)) - #:second 2) - ]} +@defexamples[ +(define greet + (lambda (given [surname "Smith"]) + (string-append "Hello, " given " " surname))) - @item{The previous two possibilities can be combined to specify a - by-keyword argument with a default value. +(greet "John") +(greet "John" "Doe") +] - @examples[ - ((lambda (x #:second [y 5]) (list x y)) - 1 #:second 2) - ((lambda (x #:second [y 5]) (list x y)) - 1) - ]} +@def+int[ +(define greet + (lambda (given [surname (if (equal? given "John") + "Doe" + "Smith")]) + (string-append "Hello, " given " " surname))) -} +(greet "John") +(greet "Adam") +] + +@section{Keyword Arguments} + +A @scheme[lambda] form can declare an argument to be passed by +keyword, instead of position. Keyword arguments can be mixed with +by-position arguments, and default-value expressions can be supplied +for either kind of argument: + +@specform/subs[ +(lambda (arg ...+ . rest-id) + body ...+) +([arg arg-id + [arg-id default-expr] + (code:line arg-keyword arg-id) + (code:line arg-keyword [arg-id default-expr])]) +]{} + +As argument specified as @scheme[(code:line _arg-keyword _arg-id)] is +supplied by an application using the same @scheme[_arg-keyword]. The +position of the keyword--identifier pair in the argument list does not +matter for matching with arguments in an application, because it will +be matched to an argument value by keyword instead of by position. + +@def+int[ +(define greet + (lambda (given #:last surname) + (string-append "Hello, " given " " surname))) + +(greet "John" #:last "Smith") +(greet #:last "Doe" "John") +] + +A @scheme[(code:line _arg-keyword [_arg-id _default-expr])] argument +specifies a keyword-based argument with a default value. + +@defexamples[ +(define greet + (lambda (#:hi [hi "Hello"] given #:last [surname "Smith"]) + (string-append hi ", " given " " surname))) + +(greet "John") +(greet "Karl" #:last "Marx") +(greet "John" #:hi "Howdy") +(greet "Karl" #:last "Marx" #:hi "Guten Tag") +] + +@;------------------------------------------------------------------------ +@section{Arity-Sensitive Procedures: @scheme[case-lambda]} The @scheme[case-lambda] form creates a procedure that can have completely different behaviors depending on the number of arguments that are supplied. A case-lambda expression has the form -@specform[ +@specform/subs[ (case-lambda - [formals body-expr ...+] + [formals body ...+] ...) +([formals (arg-id ...) + rest-id + (arg-id ...+ . rest-id)]) ] -where each @scheme[_formals _body-expr ...+] is anlogous to -@scheme[(lambda _formals _body-expr ...+)]. That is, a -@scheme[_formals] can be @scheme[(_arg-id ...)], @scheme[_rest-id], or -@scheme[(_arg-id ... . _rest-id)]. +where each @scheme[_formals _body ...+] is anlogous to @scheme[(lambda +_formals _body ...+)]. Applying a procedure produced by +@scheme[case-lambda] is like applying a @scheme[lambda] for the first +case that matches the number of given arguments. -Applying a procedure produced by @scheme[case-lambda] is like applying -a @scheme[lambda] for the first case that matches the number of given -arguments. +@defexamples[ +(define greet + (case-lambda + [(name) (string-append "Hello, " name)] + [(given surname) (string-append "Hello, " given " " surname)])) -@examples[ -((case-lambda [() 10][(x y) (+ x y)]) - 1 2) -((case-lambda [() 10][(x y) (+ x y)])) -((case-lambda [() 10][(x y) (+ x y)]) - 1) +(greet "John") +(greet "John" "Smith") +(greet) ] A @scheme[case-lambda] procedure cannot directly support optional or diff --git a/collects/scribblings/guide/lists.scrbl b/collects/scribblings/guide/lists.scrbl index 07667cf4cf..d62bc7ce08 100644 --- a/collects/scribblings/guide/lists.scrbl +++ b/collects/scribblings/guide/lists.scrbl @@ -179,7 +179,7 @@ With these pieces, you can write your own versions of the ] If the derivation of the above definitions is mysterious to you, -consider reading @|HtDP|. But if you are merely suspicious of the use +consider reading @|HtDP|. If you are merely suspicious of the use of recursive calls instead of a looping construct, then read on. Both the @scheme[my-length] and @scheme[my-map] procedures run in diff --git a/collects/scribblings/guide/numbers.scrbl b/collects/scribblings/guide/numbers.scrbl index 79a6ce618a..071654d86d 100644 --- a/collects/scribblings/guide/numbers.scrbl +++ b/collects/scribblings/guide/numbers.scrbl @@ -53,7 +53,7 @@ or inexact number. The prefixes @litchar{#b}, @litchar{#o}, and @litchar{#x} specificy binary, octal, and hexadecimal interprertation of digits. -@refdetails["mz:parse-number"]{the syntax of numbers} +@refdetails/gory["mz:parse-number"]{the syntax of numbers} @examples[ 0.5 diff --git a/collects/scribblings/guide/paths.scrbl b/collects/scribblings/guide/paths.scrbl index 4af2aa3da6..ebd91f8609 100644 --- a/collects/scribblings/guide/paths.scrbl +++ b/collects/scribblings/guide/paths.scrbl @@ -43,7 +43,9 @@ with @file{~}---which looks like a reference to the current user's home directory, instead of a relative path to a file of directory named @file{~}. Windows path manipulation, furthermore, is far trickier, because path elements like @file{aux} can have special -meanings (see @secref["windows-path"]). +meanings. + +@refdetails/gory["mz:windows-path"]{Windows filesystem paths} Use procedures like @scheme[split-path] and @scheme[build-path] to deconstruct and construct paths. When you must manipulate the name of diff --git a/collects/scribblings/guide/simple-syntax.scrbl b/collects/scribblings/guide/simple-syntax.scrbl index d62d37c4e6..836b32d515 100644 --- a/collects/scribblings/guide/simple-syntax.scrbl +++ b/collects/scribblings/guide/simple-syntax.scrbl @@ -47,7 +47,7 @@ a sequence as an element for repetition. @define[and-expr-stx @BNF-seq[@litchar{(} @litchar{and} @kleenestar{@nonterm{expr}} @litchar{)}]] @define[or-expr-stx @BNF-seq[@litchar{(} @litchar{or} @kleenestar{@nonterm{expr}} @litchar{)}]] @define[cond-expr-stx @BNF-seq[@litchar{(} @litchar{cond} - @kleenestar{@BNF-group[@litchar{[} @nonterm{expr} @nonterm{expr} @litchar{]}]} + @kleenestar{@BNF-group[@litchar{[} @nonterm{expr} @kleenestar{@nonterm{expr}} @litchar{]}]} @litchar{)}]] @define[(make-let-expr-stx kw) @BNF-seq[@litchar{(} kw @litchar{(} @@ -328,13 +328,13 @@ The shorthand for a sequence of tests is the @scheme[cond] form: A @scheme[cond] form contains a sequence of clauses between square brackets. In each clause, the first @nonterm{expr} is a test -expression. If it produces true, then the clause's second -@nonterm{expr} provides the answer for the entire @scheme[cond] -expression, and the rest of the clauses are ignored. If the test -@nonterm{expr} produces @scheme[#f], then the clause's second -@nonterm{expr} is ignored, and evaluation continues with the -next clause. The last clause can use @scheme[else] as a synonym for -a @scheme[#t] test expression. +expression. If it produces true, then the clause's remaining +@nonterm{expr}s are evaluated, and the last one in the clause provides +the answer for the entire @scheme[cond] expression; the rest of the +clauses are ignored. If the test @nonterm{expr} produces @scheme[#f], +then the clause's remaining @nonterm{expr}s are ignored, and +evaluation continues with the next clause. The last clause can use +@scheme[else] as a synonym for a @scheme[#t] test expression. Using @scheme[cond], the @scheme[reply-more] procedure can be more clearly written as follows: diff --git a/collects/scribblings/guide/symbols.scrbl b/collects/scribblings/guide/symbols.scrbl index a3d6b51939..4f8d512bb1 100644 --- a/collects/scribblings/guide/symbols.scrbl +++ b/collects/scribblings/guide/symbols.scrbl @@ -59,7 +59,7 @@ special characters or that might otherwise look like numbers. (string->symbol "6") ] -@refdetails["mz:parse-symbol"]{the syntax of symbols} +@refdetails/gory["mz:parse-symbol"]{the syntax of symbols} The @scheme[display] form of a symbol is the same as the corresponding string. diff --git a/collects/scribblings/guide/truth.scrbl b/collects/scribblings/guide/truth.scrbl index 0f69d237cd..f9c30e160e 100644 --- a/collects/scribblings/guide/truth.scrbl +++ b/collects/scribblings/guide/truth.scrbl @@ -183,7 +183,7 @@ Beware, however, that the REPL's printer recognizes the symbol ] @;------------------------------------------------------------------------ -@section{Lists and Scheme Syntax} +@section[#:tag "guide:lists-and-syntax"]{Lists and Scheme Syntax} Now that you know the truth about pairs and lists, and now that you've seen @scheme[quote], you're ready to understand the main way in which diff --git a/collects/scribblings/guide/vectors.scrbl b/collects/scribblings/guide/vectors.scrbl index 9b94c2f0c3..8c21f209eb 100644 --- a/collects/scribblings/guide/vectors.scrbl +++ b/collects/scribblings/guide/vectors.scrbl @@ -16,7 +16,7 @@ expression. Also, a vector as an expression implicitly quotes the forms for its content, which means that identifiers and parenthesized forms in a vector constant represent symbols and lists. -@refdetails["mz:parse-vector"]{the syntax of vectors} +@refdetails/gory["mz:parse-vector"]{the syntax of vectors} @examples[ (eval:alts #, @schemevalfont{#("a" "b" "c")} #("a" "b" "c")) diff --git a/collects/scribblings/reference/bytes.scrbl b/collects/scribblings/reference/bytes.scrbl index 2753d19b4d..a114a2341d 100644 --- a/collects/scribblings/reference/bytes.scrbl +++ b/collects/scribblings/reference/bytes.scrbl @@ -13,7 +13,7 @@ A @pidefterm{byte string} is a fixed-length arary of bytes. A @defterm{mutable} or @defterm{immutable}. When an immutable byte string is provided to a procedure like @scheme[bytes-set!], the @exnraise[exn:fail:contract]. Byte-string constants generated by the -default reader (see @secref["parse-string"]) are immutable. +default reader (see @secref["mz:parse-string"]) are immutable. Two byte strings are @scheme[eq?] when mutating one would mutate the other. Two byte strings are @scheme[eqv?] and @scheme[equal?] when diff --git a/collects/scribblings/reference/chars.scrbl b/collects/scribblings/reference/chars.scrbl index 0ee49a609e..cc9e86a18c 100644 --- a/collects/scribblings/reference/chars.scrbl +++ b/collects/scribblings/reference/chars.scrbl @@ -7,3 +7,14 @@ A @pidefterm{character} corresponds to a Unicode scalar value (i.e., a Unicode code point that is not a surrogate). + +@; ---------------------------------------- +@section{Classifications} + +@defproc[(char-alphabetic? [char character?]) boolean?]{ +Returns @scheme[#t] if @scheme[char] is alphabetic... +} + +@defproc[(char-whitespace? [char character?]) boolean?]{ +Returns @scheme[#t] if @scheme[char] is whitespace... +} \ No newline at end of file diff --git a/collects/scribblings/reference/data.scrbl b/collects/scribblings/reference/data.scrbl index 402120de95..b878ee2786 100644 --- a/collects/scribblings/reference/data.scrbl +++ b/collects/scribblings/reference/data.scrbl @@ -34,14 +34,14 @@ is @scheme[#t] or @scheme[#f], @scheme[#f] otherwise.} @include-section["chars.scrbl"] @; ------------------------------------------------------------ -@section[#:tag "symbols"]{Symbols} +@section[#:tag "mz:symbols"]{Symbols} @guideintro["guide:symbols"]{symbols} A symbol is like an immutable string, but symbols are normally @index["interned symbols"]{@defterm{interned}}, so that two symbols with the same character content are normally @scheme[eq?]. All symbols -produced by the default reader (see @secref["parse-symbol"]) are +produced by the default reader (see @secref["mz:parse-symbol"]) are interned. @index['("symbols" "generating")]{@index['("symbols" "unique")]{The}} two @@ -54,8 +54,8 @@ Regular (interned) symbols are only weakly held by the internal symbol table. This weakness can never affect the result of an @scheme[eq?], @scheme[eqv?], or @scheme[equal?] test, but a symbol may disappear when placed into a weak box (see @secref["weakbox"]) used as the key -in a weak hash table (see @secref["hashtable"]), or used as an -ephemeron key (see @secref["ephemeron"]). +in a weak hash table (see @secref["mz:hashtables"]), or used as an +ephemeron key (see @secref["mz:ephemerons"]). @defproc[(symbol? [v any/c]) boolean?]{Returns @scheme[#t] if @scheme[v] is a symbol, @scheme[#f] otherwise.} @@ -190,13 +190,19 @@ If the @scheme[lst]s are empty, then @scheme[#f] is returned.} ignored.} +@; ------------------------------------------------------------ +@section[#:tag "mz:vectors"]{Vectors} + +@; ------------------------------------------------------------ +@section[#:tag "mz:boxes"]{Boxes} + @; ---------------------------------------------------------------------- -@section[#:tag "hashtables"]{Hash Tables} +@section[#:tag "mz:hashtables"]{Hash Tables} @; ---------------------------------------------------------------------- @include-section["sequences.scrbl"] -@section[#:tag "procedures"]{Procedures} +@section[#:tag "mz:procedures"]{Procedures} @; ---------------------------------------------------------------------- @section[#:tag "void"]{Void and Undefined} diff --git a/collects/scribblings/reference/derived.scrbl b/collects/scribblings/reference/derived.scrbl index f58f8ee463..dbdcb01efc 100644 --- a/collects/scribblings/reference/derived.scrbl +++ b/collects/scribblings/reference/derived.scrbl @@ -1,211 +1,8 @@ #reader(lib "docreader.ss" "scribble") @require["mz.ss"] -@interaction-eval[(require (lib "for.ss"))] +@title[#:tag "mz:derived-syntax" #:style 'toc]{Derived Syntactic Forms} -@title[#:tag "mz:derived-syntax"]{Derived Syntactic Forms} - -@section[#:tag "mz:for"]{Iterations and Comprehensions: @scheme[for], @scheme[for/list], ...} - -@guideintro["guide:for"]{iterations and comprehensions} - -@defform/subs[(for (for-clause ...) . body) - ([for-clause [id seq-expr] - [(id ...) seq-expr] - (code:line #:when guard-expr)])]{ - -Iteratively evaluates @scheme[body]. The @scheme[for-clause]s -introduce bindings whose scope inculdes @scheme[body] and that -determine the number of times that @scheme[body] is evaluated. - -In the simple case, each @scheme[for-clause] has one of its first two -forms, where @scheme[[id seq-expr]] is a shorthand for @scheme[[(id -...) seq-expr]]. In this simple case, the @scheme[seq-expr]s are -evaluated left-to-right, and each must produce a sequence value (see -@secref["mz:sequences"]). - -The @scheme[for] form iterates by drawing an element from each -sequence; if any sequence is empty, then the iteration stops, and -@|void-const| is the result of the @scheme[for] expression. Otherwise -a location is created for each @scheme[id] to hold the values of each -element; the sequence produced by a @scheme[seq-expr] must return as -many values for each iteration as corresponding @scheme[id]s. - -The @scheme[id]s are then bound in the @scheme[body], which is -evaluated, and whose results are ignored. Iteration continues with the -next element in each sequence and with fresh locations for each -@scheme[id]. - -A @scheme[for] form with zero @scheme[for-clause]s is equivalent to a -single @scheme[for-clause] that binds an unreferenced @scheme[id] to -a sequence containing a single element. All of the @scheme[id]s must -be distinct according to @scheme[bound-identifier=?]. - -If any @scheme[for-clause] has the form @scheme[#:when guard-expr], -then only the preceding clauses (containing no @scheme[#:when]) -determine iteration as above, and the @scheme[body] is effectively -wrapped as - -@schemeblock[ -(when guard-expr - (for (for-clause ...) . body)) -] - -using the remaining @scheme[for-clauses]. - -@examples[ -(for ([i '(1 2 3)] - [j "abc"] - #:when (odd? i) - [k #2(#t #f)]) - (display (list i j k))) -(for ([(i j) #hash(("a" . 1) ("b" . 20))]) - (display (list i j))) -(for () - (display "here")) -(for ([i '()]) - (error "doesn't get here")) -]} - -@defform[(for/list (for-clause ...) . body)]{ Iterates like -@scheme[for], but that the last expression of @scheme[body] must -produce a single value, and the result of the @scheme[for/list] -expression is a list of the results in order. - -@examples[ -(for/list ([i '(1 2 3)] - [j "abc"] - #:when (odd? i) - [k #2(#t #f)]) - (list i j k)) -(for/list () 'any) -(for/list ([i '()]) - (error "doesn't get here")) -]} - -@defform[(for/and (for-clause ...) . body)]{ Iterates like -@scheme[for], but when last expression of @scheme[body] produces -@scheme[#f], then iteration terminates, and the result of the -@scheme[for/and] expression is @scheme[#f]. If the @scheme[body] -is never evaluated, then the result of the @scheme[for/and] -expression is @scheme[#t]. Otherwise, the result is the (single) -result from the last evaluation of @scheme[body]. - -@examples[ -(for/and ([i '(1 2 3 "x")]) - (i . < . 3)) -(for/and ([i '(1 2 3 4)]) - i) -(for/and ([i '()]) - (error "doesn't get here")) -]} - -@defform[(for/or (for-clause ...) . body)]{ Iterates like -@scheme[for], but when last expression of @scheme[body] produces -a value other than @scheme[#f], then iteration terminates, and -the result of the @scheme[for/or] expression is the same -(single) value. If the @scheme[body] is never evaluated, then the -result of the @scheme[for/or] expression is -@scheme[#f]. Otherwise, the result is @scheme[#f]. - -@examples[ -(for/or ([i '(1 2 3 "x")]) - (i . < . 3)) -(for/or ([i '(1 2 3 4)]) - i) -(for/or ([i '()]) - (error "doesn't get here")) -]} - -@defform[(for/first (for-clause ...) . body)]{ Iterates like -@scheme[for], but after @scheme[body] is evaluated the first -time, then the iteration terminates, and the @scheme[for/first] -result is the (single) result of @scheme[body]. If the -@scheme[body] is never evaluated, then the result of the -@scheme[for/first] expression is @scheme[#f]. - -@examples[ -(for/first ([i '(1 2 3 "x")] - #:when (even? i)) - (number->string i)) -(for/first ([i '()]) - (error "doesn't get here")) -]} - -@defform[(for/last (for-clause ...) . body)]{ Iterates like -@scheme[for], but the @scheme[for/last] result is the (single) -result of of the last evaluation of @scheme[body]. If the -@scheme[body] is never evaluated, then the result of the -@scheme[for/last] expression is @scheme[#f]. - -@examples[ -(for/last ([i '(1 2 3 4 5)] - #:when (even? i)) - (number->string i)) -(for/last ([i '()]) - (error "doesn't get here")) -]} - -@defform[(for/fold ([accum-id init-expr] ...) (for-clause ...). body)]{ - -Iterates like @scheme[for]. Before iteration starts, the -@scheme[init-expr]s are evaluated to produce initial accumulator -values. At the start of each out iteration, a location is generated -for each @scheme[accum-id], and the correspinding current accumulator -value is placed into the location. The last expression in -@scheme[body] must produce as many values as @scheme[accum-id]s, and -those values become the current accumulator values. When iteration -terminates, the results of the @scheme[fold/for] expression are the -accumulator values. - -@examples[ -(for/fold ([sum 0] - [rev-roots null]) - ([i '(1 2 3 4)]) - (values (+ sum i) (cons (sqrt i) rev-roots))) -]} - -@defform[(for* (for-clause ...) . body)]{ -Like @scheme[for], but with an implicit @scheme[#:when #t] between -each pair of @scheme[for-clauses], so that all sequence iterations are -nested. - -@examples[ -(for* ([i '(1 2)] - [j "ab"]) - (display (list i j))) -]} - -@defform[(for*/list (for-clause ...) . body)]{ -Like @scheme[for/list], but with the implicit nesting of @scheme[for*]. -@examples[ -(for*/list ([i '(1 2)] - [j "ab"]) - (list i j)) -]} - -@defform[(for*/and (for-clause ...) . body)]{ -Like @scheme[for/and], but with the implicit nesting of @scheme[for*].} - -@defform[(for*/or (for-clause ...) . body)]{ -Like @scheme[for/or], but with the implicit nesting of @scheme[for*].} - -@defform[(for*/first (for-clause ...) . body)]{ -Like @scheme[for/first], but with the implicit nesting of @scheme[for*].} - -@defform[(for*/last (for-clause ...) . body)]{ -Like @scheme[for/last], but with the implicit nesting of @scheme[for*].} - -@defform[(for*/fold ([accum-id init-expr] ...) (for-clause ...) . body)]{ -Like @scheme[for/fold], but with the implicit nesting of @scheme[for*].} - -@defform[(for/fold/derived orig-datum - ([accum-id init-expr] ...) (for-clause ...) . body)]{ -Like @scheme[fold/fold], but the extra @scheme[orig-datum] is used as the source for all syntax errors. -} - -@defform[(for*/fold/derived orig-datum - ([accum-id init-expr] ...) (for-clause ...) . body)]{ -Like @scheme[fold*/fold], but the extra @scheme[orig-datum] is used as the source for all syntax errors. -} +@local-table-of-contents[] +@include-section["for.scrbl"] diff --git a/collects/scribblings/reference/for.scrbl b/collects/scribblings/reference/for.scrbl new file mode 100644 index 0000000000..a9dec0dbb9 --- /dev/null +++ b/collects/scribblings/reference/for.scrbl @@ -0,0 +1,281 @@ +#reader(lib "docreader.ss" "scribble") +@require["mz.ss"] + +@interaction-eval[(require (lib "for.ss"))] + +@title[#:tag "mz:for"]{Iterations and Comprehensions: @scheme[for], @scheme[for/list], ...} + +@guideintro["guide:for"]{iterations and comprehensions} + +The PLT Scheme iteration forms are based on SRFI-42 +@cite[#:key "srfi-42" + #:title "SRFI-42: Eager Comprehensions" + #:author "Sebastian Egner" + #:location "http://srfi.schemers.org/srfi-42/" + #:date "2003"]. + +@section{Iteration and Comprehension Forms} + +@defform/subs[(for (for-clause ...) . body) + ([for-clause [id seq-expr] + [(id ...) seq-expr] + (code:line #:when guard-expr)])]{ + +Iteratively evaluates @scheme[body]. The @scheme[for-clause]s +introduce bindings whose scope inculdes @scheme[body] and that +determine the number of times that @scheme[body] is evaluated. + +In the simple case, each @scheme[for-clause] has one of its first two +forms, where @scheme[[id seq-expr]] is a shorthand for @scheme[[(id +...) seq-expr]]. In this simple case, the @scheme[seq-expr]s are +evaluated left-to-right, and each must produce a sequence value (see +@secref["mz:sequences"]). + +The @scheme[for] form iterates by drawing an element from each +sequence; if any sequence is empty, then the iteration stops, and +@|void-const| is the result of the @scheme[for] expression. Otherwise +a location is created for each @scheme[id] to hold the values of each +element; the sequence produced by a @scheme[seq-expr] must return as +many values for each iteration as corresponding @scheme[id]s. + +The @scheme[id]s are then bound in the @scheme[body], which is +evaluated, and whose results are ignored. Iteration continues with the +next element in each sequence and with fresh locations for each +@scheme[id]. + +A @scheme[for] form with zero @scheme[for-clause]s is equivalent to a +single @scheme[for-clause] that binds an unreferenced @scheme[id] to +a sequence containing a single element. All of the @scheme[id]s must +be distinct according to @scheme[bound-identifier=?]. + +If any @scheme[for-clause] has the form @scheme[#:when guard-expr], +then only the preceding clauses (containing no @scheme[#:when]) +determine iteration as above, and the @scheme[body] is effectively +wrapped as + +@schemeblock[ +(when guard-expr + (for (for-clause ...) . body)) +] + +using the remaining @scheme[for-clauses]. + +@examples[ +(for ([i '(1 2 3)] + [j "abc"] + #:when (odd? i) + [k #2(#t #f)]) + (display (list i j k))) +(for ([(i j) #hash(("a" . 1) ("b" . 20))]) + (display (list i j))) +(for () + (display "here")) +(for ([i '()]) + (error "doesn't get here")) +]} + +@defform[(for/list (for-clause ...) . body)]{ Iterates like +@scheme[for], but that the last expression of @scheme[body] must +produce a single value, and the result of the @scheme[for/list] +expression is a list of the results in order. + +@examples[ +(for/list ([i '(1 2 3)] + [j "abc"] + #:when (odd? i) + [k #2(#t #f)]) + (list i j k)) +(for/list () 'any) +(for/list ([i '()]) + (error "doesn't get here")) +]} + +@defform[(for/and (for-clause ...) . body)]{ Iterates like +@scheme[for], but when last expression of @scheme[body] produces +@scheme[#f], then iteration terminates, and the result of the +@scheme[for/and] expression is @scheme[#f]. If the @scheme[body] +is never evaluated, then the result of the @scheme[for/and] +expression is @scheme[#t]. Otherwise, the result is the (single) +result from the last evaluation of @scheme[body]. + +@examples[ +(for/and ([i '(1 2 3 "x")]) + (i . < . 3)) +(for/and ([i '(1 2 3 4)]) + i) +(for/and ([i '()]) + (error "doesn't get here")) +]} + +@defform[(for/or (for-clause ...) . body)]{ Iterates like +@scheme[for], but when last expression of @scheme[body] produces +a value other than @scheme[#f], then iteration terminates, and +the result of the @scheme[for/or] expression is the same +(single) value. If the @scheme[body] is never evaluated, then the +result of the @scheme[for/or] expression is +@scheme[#f]. Otherwise, the result is @scheme[#f]. + +@examples[ +(for/or ([i '(1 2 3 "x")]) + (i . < . 3)) +(for/or ([i '(1 2 3 4)]) + i) +(for/or ([i '()]) + (error "doesn't get here")) +]} + +@defform[(for/first (for-clause ...) . body)]{ Iterates like +@scheme[for], but after @scheme[body] is evaluated the first +time, then the iteration terminates, and the @scheme[for/first] +result is the (single) result of @scheme[body]. If the +@scheme[body] is never evaluated, then the result of the +@scheme[for/first] expression is @scheme[#f]. + +@examples[ +(for/first ([i '(1 2 3 "x")] + #:when (even? i)) + (number->string i)) +(for/first ([i '()]) + (error "doesn't get here")) +]} + +@defform[(for/last (for-clause ...) . body)]{ Iterates like +@scheme[for], but the @scheme[for/last] result is the (single) +result of of the last evaluation of @scheme[body]. If the +@scheme[body] is never evaluated, then the result of the +@scheme[for/last] expression is @scheme[#f]. + +@examples[ +(for/last ([i '(1 2 3 4 5)] + #:when (even? i)) + (number->string i)) +(for/last ([i '()]) + (error "doesn't get here")) +]} + +@defform[(for/fold ([accum-id init-expr] ...) (for-clause ...). body)]{ + +Iterates like @scheme[for]. Before iteration starts, the +@scheme[init-expr]s are evaluated to produce initial accumulator +values. At the start of each out iteration, a location is generated +for each @scheme[accum-id], and the correspinding current accumulator +value is placed into the location. The last expression in +@scheme[body] must produce as many values as @scheme[accum-id]s, and +those values become the current accumulator values. When iteration +terminates, the results of the @scheme[fold/for] expression are the +accumulator values. + +@examples[ +(for/fold ([sum 0] + [rev-roots null]) + ([i '(1 2 3 4)]) + (values (+ sum i) (cons (sqrt i) rev-roots))) +]} + +@defform[(for* (for-clause ...) . body)]{ +Like @scheme[for], but with an implicit @scheme[#:when #t] between +each pair of @scheme[for-clauses], so that all sequence iterations are +nested. + +@examples[ +(for* ([i '(1 2)] + [j "ab"]) + (display (list i j))) +]} + +@defform[(for*/list (for-clause ...) . body)]{ +Like @scheme[for/list], but with the implicit nesting of @scheme[for*]. +@examples[ +(for*/list ([i '(1 2)] + [j "ab"]) + (list i j)) +]} + +@defform[(for*/and (for-clause ...) . body)]{ +Like @scheme[for/and], but with the implicit nesting of @scheme[for*].} + +@defform[(for*/or (for-clause ...) . body)]{ +Like @scheme[for/or], but with the implicit nesting of @scheme[for*].} + +@defform[(for*/first (for-clause ...) . body)]{ +Like @scheme[for/first], but with the implicit nesting of @scheme[for*].} + +@defform[(for*/last (for-clause ...) . body)]{ +Like @scheme[for/last], but with the implicit nesting of @scheme[for*].} + +@defform[(for*/fold ([accum-id init-expr] ...) (for-clause ...) . body)]{ +Like @scheme[for/fold], but with the implicit nesting of @scheme[for*].} + +@;------------------------------------------------------------------------ +@section{Deriving New Iteration Forms} + +@defform[(for/fold/derived orig-datum + ([accum-id init-expr] ...) (for-clause ...) . body)]{ +Like @scheme[fold/fold], but the extra @scheme[orig-datum] is used as the source for all syntax errors. +} + +@defform[(for*/fold/derived orig-datum + ([accum-id init-expr] ...) (for-clause ...) . body)]{ +Like @scheme[fold*/fold], but the extra @scheme[orig-datum] is used as the source for all syntax errors. +} + +@defform[(define-sequence-syntax id + expr-transform-expr + clause-transform-expr)]{ + +Defines @scheme[id] as syntax. An @scheme[(id . _rest)] form is +treated specially when used to generate a sequence in a +@scheme[_clause] of @scheme[for] (or one of its variants). In that +case, the procedure result of @scheme[clause-transform-expr] is called +to transform the clause. + +When @scheme[id] is used in any other expression position, the result +of @scheme[expr-transform-expr] is used; if it is an identifier +@scheme[_other-id], then any use of @scheme[id] is converted to a use +of @scheme[_other-id]; otherwise,@scheme[expr-transform-expr] must +produce a procedure that is used as a macro transformer. + + +When the @scheme[clause-transform-expr] transformer is used, it is +given a @scheme[_clause] as an argument, where the clause's form is +normalized so that the left-hand side is a parenthesized sequence of +identifiers. The right-hand side is of the form @scheme[(id . _rest)]. +The result can be either @scheme[#f], to indicate that the forms +should not be treated specially (perhaps because the number of bound +identifiers is inconsistent with the @scheme[(id . _rest)] form), or a +new @scheme[_clause] to to replace the given one. The new clause might +use @scheme[:do-in].} + +@defform[(:do-in ([(outer-id ...) outer-expr] ...) + outer-check + ([loop-id loop-expr] ...) + pos-guard + ([(inner-id ...) inner-expr] ...) + pre-guard + post-guard + (loop-arg ...))]{ + +A form that can only be used as a @scheme[_seq-expr] in a +@scheme[_clause] of @scheme[for] (or one of its variants). + +Within a @scheme[for], the pieces of the @scheme[:do-in] form are +spliced into the iteration essentially as follows: + +@schemeblock[ +(let-values ([(outer-id ...) outer-expr] ...) + outer-check + (let loop ([loop-id loop-expr] ...) + (if pos-guard + (let-values ([(inner-id ...) inner-expr] ...) + (if pre-guard + (let _body-bindings + (loop loop-arg ...)) + _done-expr)) + _done-expr))) +] + +where @scheme[_body-bindings] and @scheme[_done-expr] are from the +context of the @scheme[:do-in] use. The actual @scheme[loop] binding +and call has additional loop arguments to support iterations in +parallel with the @scheme[:do-in] form, and the other pieces are +similarly accompanied by pieces form parallel iterations.} diff --git a/collects/scribblings/reference/macros.scrbl b/collects/scribblings/reference/macros.scrbl index 1f8b477eb8..9f9104ef5b 100644 --- a/collects/scribblings/reference/macros.scrbl +++ b/collects/scribblings/reference/macros.scrbl @@ -101,6 +101,10 @@ possible contexts are as follows: } +@section[#:tag "mz:intdef-body"]{Internal Definitions} + +@section{Fully Expanded Programs} + A fully expanded program---that is, a parsed program---is represented in the same way as an unparsed program: as a syntax-wrapped combination of symbols, pairs, and other values. However, a fully diff --git a/collects/scribblings/reference/numbers.scrbl b/collects/scribblings/reference/numbers.scrbl index 28148c6082..5bc8a32fb2 100644 --- a/collects/scribblings/reference/numbers.scrbl +++ b/collects/scribblings/reference/numbers.scrbl @@ -188,13 +188,13 @@ noted above). Two numbers are @scheme[equal?] when they are @examples[(/ 3 4) (/ 81 3 3) (/ 10.0) (/ 1+2i 3+4i)] -@defproc[(quotient [n integer?] [m integer?]) number?]{ Returns +@defproc[(quotient [n integer?] [m integer?]) integer?]{ Returns @scheme[(truncate (/ n m))].} @examples[(quotient 10 3) (quotient -10.0 3) (quotient +inf.0 3)] -@defproc[(remainder [n integer?] [m integer?]) number?]{ Returns +@defproc[(remainder [n integer?] [m integer?]) integer?]{ Returns @scheme[q] with the same sign as @scheme[n] such that @itemize{ @@ -208,6 +208,15 @@ noted above). Two numbers are @scheme[equal?] when they are @examples[(remainder 10 3) (remainder -10.0 3) (remainder 10.0 -3) (remainder -10 -3) (remainder +inf.0 3)]} +@defproc[(quotient/remainder [n integer?] [m integer?]) (values number? number?)]{ Returns + @scheme[(values (quotient n m) (remainder n m))], but the combination is computed + more efficiently than separate calls to @scheme[quotient] and @scheme[remainder]. + +@examples[ +(quotient/remainder 10 3) +]} + + @defproc[(modulo [n integer?] [m integer?]) number?]{ Returns @scheme[q] with the same sign as @scheme[m] where @@ -534,7 +543,7 @@ noted above). Two numbers are @scheme[equal?] when they are @defproc[(string->number [s string?] [radix (exact-integer-in/c 2 16) 10]) (or/c number? false/c)]{ Reads and returns a number datum from - @scheme[s] (see @secref["parse-number"]), returning @scheme[#f] if + @scheme[s] (see @secref["mz:parse-number"]), returning @scheme[#f] if @scheme[s] does not parse exactly as a number datum (with no whitespace). The optional @scheme[radix] argument specifies the default base for the number, which can be overriden by @litchar{#b}, diff --git a/collects/scribblings/reference/read.scrbl b/collects/scribblings/reference/read.scrbl index 01ab0da6a7..9169551f8f 100644 --- a/collects/scribblings/reference/read.scrbl +++ b/collects/scribblings/reference/read.scrbl @@ -18,7 +18,7 @@ @title[#:tag "mz:reader"]{Reading} Scheme's reader is a recursive-descent parser that can be configured -through a @seclink["readtable"]{readtable} and various other +through a @seclink["mz:readtables"]{readtable} and various other @seclink["parameters"]{parameters}. This section describes the reader's parsing when using the default readtable. @@ -37,10 +37,10 @@ reader's behavior in @scheme[read] mode, and @scheme[read-syntax] mode does the same modulo wrapping the final result. Reading is defined in terms of Unicode characters; see -@secref["unicode"] for information on how a byte stream is converted +@secref["mz:char-input"] for information on how a byte stream is converted to a character stream. -@section{Delimiters and Dispatch} +@section[#:tag "mz:default-readtable-dispatch"]{Delimiters and Dispatch} Along with @schemelink[char-whitespace?]{whitespace}, the following characters are @defterm{delimiters}: @@ -286,7 +286,7 @@ input syntax for the boolean constant false. When the reader encounters a @as-index{@litchar{(}}, @as-index{@litchar["["]}, or @as-index{@litchar["{"]}, it starts -parsing a pair or list; see @secref["pairs"] for information on pairs +parsing a pair or list; see @secref["mz:pairs"] for information on pairs and lists. To parse the pair or list, the reader recursively reads data @@ -720,3 +720,11 @@ information on special-comment results and recursive reads. If the @scheme[read-accept-reader] parameter is set to @scheme[#f], then if the reader encounters @litchar{#reader}, the @exnraise[exn:fail:read]. + +@section[#:tag "mz:readtables"]{Readtables} + +The dispatch table in @secref["mz:default-readtable-dispatch"] +corresponds to the default @idefterm{readtable}. + +@section[#:tag "mz:parse-honu"]{Honu Parsing} + diff --git a/collects/scribblings/reference/reference.scrbl b/collects/scribblings/reference/reference.scrbl index 66a50a2e1b..73a8c13288 100644 --- a/collects/scribblings/reference/reference.scrbl +++ b/collects/scribblings/reference/reference.scrbl @@ -18,4 +18,20 @@ language. @include-section["derived.scrbl"] @include-section["data.scrbl"] +@;------------------------------------------------------------------------ + +@section["Input and Output"] + +@subsection[#:tag "mz:char-input"]{Form Bytes to Characters} + +@;------------------------------------------------------------------------ + +@section{Platform-Specific Path Conventions} + +@subsection[#:tag "mz:unix-path"]{Unix and Mac OS X Paths} + +@subsection[#:tag "mz:windows-path"]{Windows Paths} + +@;------------------------------------------------------------------------ + @index-section["mzscheme-index"] diff --git a/collects/scribblings/reference/strings.scrbl b/collects/scribblings/reference/strings.scrbl index 2d51d1b833..b0265b1667 100644 --- a/collects/scribblings/reference/strings.scrbl +++ b/collects/scribblings/reference/strings.scrbl @@ -3,16 +3,16 @@ @title[#:tag "mz:strings"]{Strings} -@guideintro["guide:string"]{strings} +@guideintro["guide:strings"]{strings} A @pidefterm{string} is a fixed-length arary of -@seclink["characters"]{characters}. +@seclink["mz:characters"]{characters}. @index['("strings" "immutable")]{A} string can be @defterm{mutable} or @defterm{immutable}. When an immutable string is provided to a procedure like @scheme[string-set!], the @exnraise[exn:fail:contract]. String constants generated by the -default reader (see @secref["parse-string"]) are +default reader (see @secref["mz:parse-string"]) are immutable. Two strings are @scheme[eq?] when mutating one would mutate the other. diff --git a/collects/scribblings/reference/syntax.scrbl b/collects/scribblings/reference/syntax.scrbl index 04aa225126..7184f297c4 100644 --- a/collects/scribblings/reference/syntax.scrbl +++ b/collects/scribblings/reference/syntax.scrbl @@ -27,9 +27,6 @@ Within such specifications, @item{@scheme[...+] indicates one or more repetitions of the preceding datum.} - @item{@scheme[?] means zero instances or one instance - of the preceding datum.} - @item{italic meta-identifier play the role of non-terminals; in particular, @@ -48,7 +45,7 @@ Within such specifications, for a non-empty syntax-wrapped list of sub-forms; the list is expanded as internal-definition sequence followed by at least one expression (see - @secref["intdef-body"] for details).} + @secref["mz:intdef-body"] for details).} }} } @@ -230,7 +227,7 @@ a sequence of @scheme[_formal-arg]s optionally ending with a list that is associated to @scheme[rest-id].} The @scheme[formals*] identifiers are bound in the @scheme[body]. (See -@secref["intdef-body"] for information on @scheme[body] forms.) When +@secref["mz:intdef-body"] for information on @scheme[body] forms.) When the procedure is applied, a new location is created for each identifier, and the location is filled with the associated argument value. @@ -299,7 +296,7 @@ support keyword and optional arguments. The first form evaluates the @scheme[val-expr]s left-to-right, creates a new location for each @scheme[id], and places the values into the locations. It then evaluates the @scheme[body], in which the -@scheme[id]s are bound. (See @secref["intdef-body"] for information +@scheme[id]s are bound. (See @secref["mz:intdef-body"] for information on @scheme[body] forms.) The last expression in @scheme[body] is in tail position with respect to the @scheme[let] form. The @scheme[id]s must be distinct according to @scheme[bound-identifier=?]. diff --git a/doc/release-notes/mred/HISTORY b/doc/release-notes/mred/HISTORY index a4702a35f2..3c92a77516 100644 --- a/doc/release-notes/mred/HISTORY +++ b/doc/release-notes/mred/HISTORY @@ -1,3 +1,9 @@ +Version 370.3 + +Fixed (get-face-list 'mono) for Mac OS X and X11 +Changed begin-container-sequence to delay making windows visible + + Version 370.2 Added 'no-focus style for canvas% diff --git a/doc/release-notes/mzscheme/HISTORY b/doc/release-notes/mzscheme/HISTORY index a7b1d1d2bc..c481d61356 100644 --- a/doc/release-notes/mzscheme/HISTORY +++ b/doc/release-notes/mzscheme/HISTORY @@ -1,4 +1,4 @@ -Version 370.2 +Version 370.3 Added hash-table-iterate-{first,next,key,value} Version 370.2