From 851c58ea50dc31c175bde7016962833f379885c6 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 5 Jan 2009 14:00:07 +0000 Subject: [PATCH] add #:contracts optional sub-form to defform svn: r13012 --- collects/scribble/private/manual-form.ss | 135 +++++++++++++----- collects/scribblings/quick/quick.scrbl | 2 +- collects/scribblings/reference/for.scrbl | 9 +- .../scribblings/reference/parameters.scrbl | 4 +- collects/scribblings/reference/syntax.scrbl | 25 ++-- collects/scribblings/scribble/manual.scrbl | 39 +++-- .../2htdp/scribblings/universe.scrbl | 105 ++++++++------ 7 files changed, 219 insertions(+), 100 deletions(-) diff --git a/collects/scribble/private/manual-form.ss b/collects/scribble/private/manual-form.ss index 76ffc10389..8b348a6bf3 100644 --- a/collects/scribble/private/manual-form.ss +++ b/collects/scribble/private/manual-form.ss @@ -32,6 +32,7 @@ (syntax-case stx () [(_ #:id defined-id #:literals (lit ...) [spec spec1 ...] ([non-term-id non-term-form ...] ...) + #:contracts ([contract-nonterm contract-expr] ...) desc ...) (with-syntax ([new-spec (let loop ([spec #'spec]) @@ -65,57 +66,83 @@ (lambda () (schemeblock0/form non-term-form)) ...) ...) + (list (list (lambda () (scheme contract-nonterm)) + (lambda () (schemeblock0 contract-expr))) + ...) (lambda () (list desc ...)))))] + [(fm #:id defined-id #:literals (lit ...) [spec spec1 ...] + ([non-term-id non-term-form ...] ...) + desc ...) + (syntax/loc stx + (fm #:id defined-id #:literals (lit ...) [spec spec1 ...] + ([non-term-id non-term-form ...] ...) + #:contracts () + desc ...))] [(fm #:id id [spec spec1 ...] ([non-term-id non-term-form ...] ...) desc ...) - #'(fm #:id id #:literals () [spec spec1 ...] + (syntax/loc stx + (fm #:id id #:literals () [spec spec1 ...] ([non-term-id non-term-form ...] ...) - desc ...)] + #:contracts () + desc ...))] [(fm #:literals lits [(spec-id . spec-rest) spec1 ...] ([non-term-id non-term-form ...] ...) desc ...) (with-syntax ([(_ _ _ [spec . _] . _) stx]) - #'(fm #:id spec-id #:literals lits [spec spec1 ...] + (syntax/loc stx + (fm #:id spec-id #:literals lits [spec spec1 ...] ([non-term-id non-term-form ...] ...) - desc ...))] + desc ...)))] [(fm [spec spec1 ...] ([non-term-id non-term-form ...] ...) desc ...) - #'(fm #:literals () [spec spec1 ...] ([non-term-id non-term-form ...] ...) - desc ...)])) + (syntax/loc stx + (fm #:literals () [spec spec1 ...] ([non-term-id non-term-form ...] ...) + desc ...))])) (define-syntax (defform* stx) (syntax-case stx () [(_ #:id id #:literals lits [spec ...] desc ...) - #'(defform*/subs #:id id #:literals lits [spec ...] () desc ...)] + (syntax/loc stx + (defform*/subs #:id id #:literals lits [spec ...] () desc ...))] [(_ #:literals lits [spec ...] desc ...) - #'(defform*/subs #:literals lits [spec ...] () desc ...)] + (syntax/loc stx + (defform*/subs #:literals lits [spec ...] () desc ...))] [(_ [spec ...] desc ...) - #'(defform*/subs [spec ...] () desc ...)])) + (syntax/loc stx + (defform*/subs [spec ...] () desc ...))])) (define-syntax (defform stx) (syntax-case stx () [(_ #:id id #:literals (lit ...) spec desc ...) - #'(defform*/subs #:id id #:literals (lit ...) [spec] () desc ...)] + (syntax/loc stx + (defform*/subs #:id id #:literals (lit ...) [spec] () desc ...))] [(_ #:id id spec desc ...) - #'(defform*/subs #:id id #:literals () [spec] () desc ...)] + (syntax/loc stx + (defform*/subs #:id id #:literals () [spec] () desc ...))] [(_ #:literals (lit ...) spec desc ...) - #'(defform*/subs #:literals (lit ...) [spec] () desc ...)] + (syntax/loc stx + (defform*/subs #:literals (lit ...) [spec] () desc ...))] [(_ spec desc ...) - #'(defform*/subs [spec] () desc ...)])) + (syntax/loc stx + (defform*/subs [spec] () desc ...))])) (define-syntax (defform/subs stx) (syntax-case stx () [(_ #:id id #:literals lits spec subs desc ...) - #'(defform*/subs #:id id #:literals lits [spec] subs desc ...)] + (syntax/loc stx + (defform*/subs #:id id #:literals lits [spec] subs desc ...))] [(_ #:id id spec subs desc ...) - #'(defform*/subs #:id id #:literals () [spec] subs desc ...)] + (syntax/loc stx + (defform*/subs #:id id #:literals () [spec] subs desc ...))] [(_ #:literals lits spec subs desc ...) - #'(defform*/subs #:literals lits [spec] subs desc ...)] + (syntax/loc stx + (defform*/subs #:literals lits [spec] subs desc ...))] [(_ spec subs desc ...) - #'(defform*/subs [spec] subs desc ...)])) + (syntax/loc stx + (defform*/subs [spec] subs desc ...))])) (define-syntax (defform/none stx) (syntax-case stx () - [(_ #:literals (lit ...) spec desc ...) + [(_ #:literals (lit ...) spec #:contracts ([contract-id contract-expr] ...) desc ...) (begin (for-each (lambda (id) (unless (identifier? id) @@ -130,9 +157,16 @@ (*defforms #f '(spec) (list (lambda (ignored) (schemeblock0/form spec))) null null + (list (list (lambda () (scheme contract-id)) + (lambda () (schemeblock0 contract-expr))) + ...) (lambda () (list desc ...)))))] - [(_ spec desc ...) - #'(defform/none #:literals () spec desc ...)])) + [(fm #:literals (lit ...) spec desc ...) + (syntax/loc stx + (fm #:literals (lit ...) spec #:contracts () desc ...))] + [(fm spec desc ...) + (syntax/loc stx + (fm #:literals () spec desc ...))])) (define-syntax (defidform stx) (syntax-case stx () @@ -145,6 +179,7 @@ (list (lambda (x) (make-omitable-paragraph (list x)))) null null + null (lambda () (list desc ...))))])) (define (into-blockquote s) @@ -164,6 +199,7 @@ (define-syntax spec?form/subs (syntax-rules () [(_ has-kw? #:literals (lit ...) spec ([non-term-id non-term-form ...] ...) + #:contracts ([contract-nonterm contract-expr] ...) desc ...) (with-scheme-variables (lit ...) @@ -175,7 +211,15 @@ (lambda () (schemeblock0/form non-term-form)) ...) ...) - (lambda () (list desc ...))))])) + (list (list (lambda () (scheme contract-nonterm)) + (lambda () (schemeblock0 contract-expr))) + ...) + (lambda () (list desc ...))))] + [(_ has-kw? #:literals (lit ...) spec ([non-term-id non-term-form ...] ...) + desc ...) + (spec?form/subs has-kw? #:literals (lit ...) spec ([non-term-id non-term-form ...] ...) + #:contracts () + desc ...)])) (define-syntax specsubform (syntax-rules () @@ -220,7 +264,7 @@ (with-scheme-variables () ([form/maybe (#f spec)]) - (*specsubform 'spec null #f null null (lambda () (list desc ...))))) + (*specsubform 'spec null #f null null null (lambda () (list desc ...))))) (define-syntax schemegrammar (syntax-rules () @@ -258,7 +302,7 @@ (define (meta-symbol? s) (memq s '(... ...+ ?))) -(define (*defforms kw-id forms form-procs subs sub-procs content-thunk) +(define (*defforms kw-id forms form-procs subs sub-procs contract-procs content-thunk) (parameterize ([current-meta-list '(... ...+)]) (make-box-splice (cons @@ -307,10 +351,11 @@ sub-procs)]) (*schemerawgrammars "specgrammar" (map car l) - (map cdr l)))))))))) + (map cdr l)))))))) + (make-contracts-table contract-procs))) (content-thunk))))) -(define (*specsubform form lits form-thunk subs sub-procs content-thunk) +(define (*specsubform form lits form-thunk subs sub-procs contract-procs content-thunk) (parameterize ([current-meta-list '(... ...+)]) (make-blockquote "leftindent" @@ -324,16 +369,18 @@ (if form-thunk (form-thunk) (make-omitable-paragraph (list (to-element form))))))) - (if (null? sub-procs) - null - (list (list flow-empty-line) - (list (make-flow - (list (let ([l (map (lambda (sub) - (map (lambda (f) (f)) sub)) - sub-procs)]) - (*schemerawgrammars "specgrammar" - (map car l) - (map cdr l)))))))))) + (append + (if (null? sub-procs) + null + (list (list flow-empty-line) + (list (make-flow + (list (let ([l (map (lambda (sub) + (map (lambda (f) (f)) sub)) + sub-procs)]) + (*schemerawgrammars "specgrammar" + (map car l) + (map cdr l)))))))) + (make-contracts-table contract-procs)))) (flow-paragraphs (decode-flow (content-thunk))))))) (define (*schemerawgrammars style nonterms clauseses) @@ -374,3 +421,21 @@ (define (*var-sym id) (string->symbol (format "_~a" id))) + +(define (make-contracts-table contract-procs) + (if (null? contract-procs) + null + (append + (list (list flow-empty-line)) + (list (list (make-flow + (map (lambda (c) + (make-table + "argcontract" + (list + (list (to-flow (hspace 2)) + (to-flow ((car c))) + flow-spacer + (to-flow ":") + flow-spacer + (make-flow (list ((cadr c)))))))) + contract-procs))))))) diff --git a/collects/scribblings/quick/quick.scrbl b/collects/scribblings/quick/quick.scrbl index 365c7a4eb0..0f589a42a0 100644 --- a/collects/scribblings/quick/quick.scrbl +++ b/collects/scribblings/quick/quick.scrbl @@ -410,7 +410,7 @@ Modules are named and distributed in various ways: @item{Some modules live relative to other modules, without necessarily belonging to any particular collection or package. - For example, in DrScheme, if save your definitions so far in a + For example, in DrScheme, if you save your definitions so far in a file @filepath{quick.ss} and add the line @schemeblock[(provide rainbow square)] diff --git a/collects/scribblings/reference/for.scrbl b/collects/scribblings/reference/for.scrbl index 66802c81b0..8222f37b6e 100644 --- a/collects/scribblings/reference/for.scrbl +++ b/collects/scribblings/reference/for.scrbl @@ -14,7 +14,8 @@ The @scheme[for] iteration forms are based on SRFI-42 @defform/subs[(for (for-clause ...) body ...+) ([for-clause [id seq-expr] [(id ...) seq-expr] - (code:line #:when guard-expr)])]{ + (code:line #:when guard-expr)]) + #:contracts ([seq-expr sequence?])]{ Iteratively evaluates @scheme[body]. The @scheme[for-clause]s introduce bindings whose scope includes @scheme[body] and that @@ -242,7 +243,11 @@ Like @scheme[for*/fold], but the extra @scheme[orig-datum] is used as the source @defform[(define-sequence-syntax id expr-transform-expr - clause-transform-expr)]{ + clause-transform-expr) + #:contracts + ([expr-transform-expr (or/c (-> identifier?) + (syntax? . -> . syntax?))] + [clause-transform-expr (syntax? . -> . syntax?)])]{ Defines @scheme[id] as syntax. An @scheme[(id . _rest)] form is treated specially when used to generate a sequence in a diff --git a/collects/scribblings/reference/parameters.scrbl b/collects/scribblings/reference/parameters.scrbl index 8a04c40e6f..0c99b660d7 100644 --- a/collects/scribblings/reference/parameters.scrbl +++ b/collects/scribblings/reference/parameters.scrbl @@ -45,7 +45,9 @@ reject a change to the parameter's value. The @scheme[guard] is not applied to the initial @scheme[v].} @defform[(parameterize ((parameter-expr value-expr) ...) - body ...+)]{ + body ...+) + #:contracts + ([parameter-expr parameter?])]{ @guideintro["parameterize"]{@scheme[parameterize]} diff --git a/collects/scribblings/reference/syntax.scrbl b/collects/scribblings/reference/syntax.scrbl index 75baa630ce..77ed5e2701 100644 --- a/collects/scribblings/reference/syntax.scrbl +++ b/collects/scribblings/reference/syntax.scrbl @@ -28,9 +28,11 @@ See @secref["fully-expanded"] for the core grammar. Each syntactic form is described by a BNF-like notation that describes a combination of (syntax-wrapped) pairs, symbols, and other data (not a sequence of characters). These grammatical specifications are shown -as follows: +as in the following specification of a @schemekeywordfont{something} +form: -@specsubform[(#, @schemekeywordfont{some-form} id ...)] +@specsubform[(#, @schemekeywordfont{something} id thing-expr ...) + #:contracts ([thing-expr number?])] Within such specifications, @@ -42,26 +44,31 @@ Within such specifications, @item{@scheme[...+] indicates one or more repetitions of the preceding datum.} - @item{italic meta-identifiers play the role of non-terminals; in - particular, + @item{Italic meta-identifiers play the role of non-terminals. Some + meta-identifier names imply syntactic constraints: @itemize{ - @item{a meta-identifier that ends in @scheme[_id] stands for an + @item{A meta-identifier that ends in @scheme[_id] stands for an identifier.} - @item{a meta-identifier that ends in @scheme[_keyword] stands + @item{A meta-identifier that ends in @scheme[_keyword] stands for a keyword.} - @item{a meta-identifier that ends with @scheme[_expr] stands - for a sub-form that is expanded as an expression.} + @item{A meta-identifier that ends with @scheme[_expr] (such as + @scheme[_thing-expr]) stands for a sub-form that is + expanded as an expression.} @item{A meta-identifier that ends with @scheme[_body] stands for a sub-form that is expanded in an internal-definition context (see @secref["intdef-body"]).} - }} } + }} + + @item{Contracts indicate constraints on sub-expression results. For + example, @scheme[_thing-expr #, @elem{:} number?] indicates that + the expression @scheme[_thing-expr] must produce a number.}} @;------------------------------------------------------------------------ @section[#:tag "module"]{Modules: @scheme[module], ...} diff --git a/collects/scribblings/scribble/manual.scrbl b/collects/scribblings/scribble/manual.scrbl index 3518eb1269..535ce73e34 100644 --- a/collects/scribblings/scribble/manual.scrbl +++ b/collects/scribblings/scribble/manual.scrbl @@ -387,15 +387,19 @@ can also be defined by a single @scheme[defproc*], for the case that it's best to document a related group of procedures at once.} -@defform/subs[(defform maybe-id maybe-literals form-datum pre-flow ...) +@defform/subs[(defform maybe-id maybe-literals form-datum maybe-contracts + pre-flow ...) ([maybe-id code:blank (code:line #:id id)] [maybe-literals code:blank - (code:line #:literals (literal-id ...))])]{ + (code:line #:literals (literal-id ...))] + [maybe-contracts code:blank + (code:line #:contracts ([subform-datum contract-expr-datum] + ...))])]{ Produces a sequence of flow elements (encapsulated in a @scheme[splice]) to document a syntatic form named by @scheme[id] -whose syntax described by @scheme[form-datum]. If no @scheme[#:id] is used +whose syntax is described by @scheme[form-datum]. If no @scheme[#:id] is used to specify @scheme[id], then @scheme[form-datum] must have the form @scheme[(id . _datum)]. @@ -414,16 +418,24 @@ non-terminal. If @scheme[#:literals] clause is provided, however, instances of the @scheme[literal-id]s are typeset normally (i.e., as determined by the enclosing context). -The typesetting of @scheme[form-datum] preserves the source layout, -like @scheme[schemeblock].} +If a @scheme[#:contracts] clause is provided, each +@scheme[subform-datum] (typically an identifier that serves as a +meta-variable in @scheme[form-datum]) is shown as producing a value +that must satisfy the contract described by @scheme[contract-expr-datum]. -@defform[(defform* maybe-id maybe-literals [form-datum ...+] pre-flow ...)]{ +The typesetting of @scheme[form-datum], @scheme[subform-datum], and +@scheme[contract-expr-datum] preserves the source layout, like +@scheme[schemeblock].} + +@defform[(defform* maybe-id maybe-literals [form-datum ...+] maybe-contracts + pre-flow ...)]{ Like @scheme[defform], but for multiple forms using the same @scheme[_id].} @defform[(defform/subs maybe-id maybe-literals form-datum ([nonterm-id clause-datum ...+] ...) + maybe-contracts pre-flow ...)]{ Like @scheme[defform], but including an auxiliary grammar of @@ -434,12 +446,14 @@ non-terminals shown with the @scheme[_id] form. Each @defform[(defform*/subs maybe-id maybe-literals [form-datum ...] + maybe-contracts pre-flow ...)]{ Like @scheme[defform/subs], but for multiple forms for @scheme[_id].} -@defform[(defform/none maybe-literal form-datum pre-flow ...)]{ +@defform[(defform/none maybe-literal form-datum maybe-contracts + pre-flow ...)]{ Like @scheme[defform], but without registering a definition.} @@ -449,14 +463,16 @@ Like @scheme[defform], but without registering a definition.} Like @scheme[defform], but with a plain @scheme[id] as the form.} -@defform[(specform maybe-literals datum pre-flow ...)]{ +@defform[(specform maybe-literals datum maybe-contracts + pre-flow ...)]{ Like @scheme[defform], but without indexing or registering a definition, and with indenting on the left for both the specification and the @scheme[pre-flow]s.} -@defform[(specsubform maybe-literals datum pre-flow ...)]{ +@defform[(specsubform maybe-literals datum maybe-contracts + pre-flow ...)]{ Similar to @scheme[defform], but without any specific identifier being defined, and the table and flow are typeset indented. This form is @@ -472,13 +488,15 @@ procedure. In this description, a reference to any identifier in @defform[(specsubform/subs maybe-literals datum ([nonterm-id clause-datum ...+] ...) + maybe-contracts pre-flow ...)]{ Like @scheme[specsubform], but with a grammar like @scheme[defform/subs].} -@defform[(specspecsubform maybe-literals datum pre-flow ...)]{ +@defform[(specspecsubform maybe-literals datum maybe-contracts + pre-flow ...)]{ Like @scheme[specsubform], but indented an extra level. Since using @scheme[specsubform] within the body of @scheme[specsubform] already @@ -488,6 +506,7 @@ without nesting a description.} @defform[(specspecsubform/subs maybe-literals datum ([nonterm-id clause-datum ...+] ...) + maybe-contracts pre-flow ...)]{ Like @scheme[specspecsubform], but with a grammar like diff --git a/collects/teachpack/2htdp/scribblings/universe.scrbl b/collects/teachpack/2htdp/scribblings/universe.scrbl index a0f6cd7983..6609c611b4 100644 --- a/collects/teachpack/2htdp/scribblings/universe.scrbl +++ b/collects/teachpack/2htdp/scribblings/universe.scrbl @@ -188,22 +188,24 @@ The design of a world program demands that you come up with a data @itemize[ @item{ -@defform[(on-tick - [tick-expr (-> (unsyntax @tech{World}) (unsyntax @tech{World}))])]{ +@defform[(on-tick tick-expr) + #:contracts + ([tick-expr (-> (unsyntax @tech{World}) (unsyntax @tech{World}))])]{ tell DrScheme to call the @scheme[tick-expr] function on the current world every time the clock ticks. The result of the call becomes the current world. The clock ticks at the rate of 28 times per second.}} @item{ -@defform/none[(on-tick - [tick-expr (-> (unsyntax @tech{World}) (unsyntax @tech{World}))] +@defform/none[(on-tick tick-expr rate-expr) + #:contracts + ([tick-expr (-> (unsyntax @tech{World}) (unsyntax @tech{World}))] [rate-expr natural-number/c])]{ tell DrScheme to call the @scheme[tick-expr] function on the current world every time the clock ticks. The result of the call becomes the current world. The clock ticks at the rate of @scheme[rate-expr].}} -@item{An @tech{KeyEvent} represents key board events, e.g., keys pressed or +@item{A @tech{KeyEvent} represents key board events, e.g., keys pressed or released. @deftech{KeyEvent} : @scheme[(or/c char? symbol?)] @@ -230,8 +232,9 @@ A character is used to signal that the user has hit an alphanumeric @defproc[(key=? [x key-event?][y key-event?]) boolean?]{ compares two @tech{KeyEvent} for equality} -@defform[(on-key - [change-expr (-> (unsyntax @tech{World}) key-event? (unsyntax @tech{World}))])]{ +@defform[(on-key change-expr) + #:contracts + ([change-expr (-> (unsyntax @tech{World}) key-event? (unsyntax @tech{World}))])]{ tell DrScheme to call @scheme[change-expr] function on the current world and a @tech{KeyEvent} for every keystroke the user of the computer makes. The result of the call becomes the current world. @@ -282,8 +285,9 @@ All @tech{MouseEvent}s are represented via symbols: @defproc[(mouse=? [x mouse-event?][y mouse-event?]) boolean?]{ compares two @tech{KeyEvent} for equality} -@defform[(on-mouse - [clack-expr +@defform[(on-mouse clack-expr) + #:contracts + ([clack-expr (-> (unsyntax @tech{World}) natural-number/c natural-number/c (unsyntax @tech{MouseEvent}) (unsyntax @tech{World}))])]{ tell DrScheme to call @scheme[clack-expr] on the current world, the current @scheme[x] and @scheme[y] coordinates of the mouse, and and a @@ -297,16 +301,18 @@ All @tech{MouseEvent}s are represented via symbols: @item{ -@defform[(on-draw - [render-expr (-> (unsyntax @tech{World}) scene?)])]{ +@defform[(on-draw render-expr) + #:contracts + ([render-expr (-> (unsyntax @tech{World}) scene?)])]{ tell DrScheme to call the function @scheme[render-expr] whenever the canvas must be drawn. The external canvas is usually re-drawn after DrScheme has dealt with an event. Its size is determined by the size of the first generated @tech{scene}.} -@defform/none[(on-draw - [render-expr (-> (unsyntax @tech{World}) scene?)] +@defform/none[(on-draw render-expr width-expr height-expr) + #:contracts + ([render-expr (-> (unsyntax @tech{World}) scene?)] [width-expr natural-number/c] [height-expr natural-number/c])]{ @@ -317,8 +323,9 @@ All @tech{MouseEvent}s are represented via symbols: @item{ -@defform[(stop-when - [last-world? (-> (unsyntax @tech{World}) boolean?)])]{ +@defform[(stop-when last-world?) + #:contracts + ([last-world? (-> (unsyntax @tech{World}) boolean?)])]{ tell DrScheme to call the @scheme[last-world?] function whenever the canvas is drawn. If this call produces @scheme[true], the world program is shut down. Specifically, the clock is stopped; no more @@ -328,8 +335,9 @@ All @tech{MouseEvent}s are represented via symbols: @item{ -@defform[(record? - [boolean-expr boolean?])]{ +@defform[(record? boolean-expr) + #:contracts + ([boolean-expr boolean?])]{ tell DrScheme to record all events and to enable a replay of the entire interaction. The replay action also generates one png image per scene and an animated gif for the entire sequence. @@ -728,21 +736,25 @@ Each world-producing callback in a world program---those for handling clock As mentioned, all event handlers may return @tech{World}s or @tech{Package}s; here are the revised specifications: -@defform/none[(on-tick - [tick-expr (-> (unsyntax @tech{World}) (or/c (unsyntax @tech{World}) package?))])]{ +@defform/none[(on-tick tick-expr) + #:contracts + ([tick-expr (-> (unsyntax @tech{World}) (or/c (unsyntax @tech{World}) package?))])]{ } -@defform/none[(on-tick - [tick-expr (-> (unsyntax @tech{World}) (or/c (unsyntax @tech{World}) package?))] +@defform/none[(on-tick tick-expr rate-expr) + #:contracts + ([tick-expr (-> (unsyntax @tech{World}) (or/c (unsyntax @tech{World}) package?))] [rate-expr natural-number/c])]{ } -@defform/none[(on-key - [change (-> (unsyntax @tech{World}) key-event? (or/c (unsyntax @tech{World}) package?))])]{ +@defform/none[(on-key change-expr) + #:contracts + ([change-expr (-> (unsyntax @tech{World}) key-event? (or/c (unsyntax @tech{World}) package?))])]{ } -@defform/none[(on-mouse - [clack +@defform/none[(on-mouse clack-expr) + #:contracts + ([clack-expr (-> (unsyntax @tech{World}) natural-number/c natural-number/c (unsyntax @tech{MouseEvent}) (or/c (unsyntax @tech{World}) package?))])]{ } @@ -780,14 +792,16 @@ following shapes: @itemize[ @item{ -@defform[(register [ip-expr string?])]{ +@defform[(register ip-expr) #:contracts ([ip-expr string?])]{ connect this world to a universe server at the specified @scheme[ip-expr] address and set up capabilities for sending and receiving messages.} } @item{ -@defform/none[(register [ip-expr string?] - [name-expr (or/c symbol? string?)])]{ +@defform/none[(register ip-expr name-expr) + #:contracts + ([ip-expr string?] + [name-expr (or/c symbol? string?)])]{ connect this world to a universe server @emph{under a specific} @scheme[name-expr].} } @@ -807,8 +821,9 @@ Finally, the receipt of a message from the server is an event, just like The @scheme[on-receive] clause of a @scheme[big-bang] specifies the event handler for message receipts. -@defform[(on-receive - [receive-expr (-> (unsyntax @tech{World}) sexp? (or/c (unsyntax @tech{World}) package?))])]{ +@defform[(on-receive receive-expr) + #:contracts + ([receive-expr (-> (unsyntax @tech{World}) sexp? (or/c (unsyntax @tech{World}) package?))])]{ tell DrScheme to call @scheme[receive-expr] for every message receipt, on the current @tech{World} and the received message. The result of the call becomes the current @tech{World}. @@ -993,15 +1008,17 @@ description. Two of them are mandatory: @itemize[ @item{ - @defform[(on-new - [new-expr (-> (unsyntax @tech{Universe}) world? + @defform[(on-new new-expr) + #:contracts + ([new-expr (-> (unsyntax @tech{Universe}) world? (cons (unsyntax @tech{Universe}) [listof mail?]))])]{ tell DrScheme to call the function @scheme[new-expr] every time another world joins the universe.}} @item{ - @defform[(on-msg - [msg-expr (-> (unsyntax @tech{Universe}) world? sexp? + @defform[(on-msg msg-expr) + #:contracts + ([msg-expr (-> (unsyntax @tech{Universe}) world? sexp? (cons (unsyntax @tech{Universe}) [listof mail?]))])]{ tell DrScheme to apply @scheme[msg-expr] to the current state of the universe, the world @@ -1020,15 +1037,17 @@ optional handlers: @itemize[ @item{ -@defform/none[(on-tick - [tick-expr (-> (unsyntax @tech{Universe}) bundle?)])]{ +@defform/none[(on-tick tick-expr) + #:contracts + ([tick-expr (-> (unsyntax @tech{Universe}) bundle?)])]{ tell DrScheme to apply @scheme[tick-expr] to the current state of the universe. The handler is expected to produce a bundle of the new state of the universe and a list of mails. } -@defform/none[(on-tick - [tick-expr (-> (unsyntax @tech{Universe}) bundle?)] +@defform/none[(on-tick tick-expr rate-expr) + #:contracts + ([tick-expr (-> (unsyntax @tech{Universe}) bundle?)] [rate-expr natural-number/c])]{ tell DrScheme to apply @scheme[tick-expr] as above but use the specified clock tick rate instead of the default. @@ -1036,8 +1055,9 @@ optional handlers: } @item{ - @defform[(on-disconnect - [dis-expr (-> (unsyntax @tech{Universe}) world? bundle?)])]{ + @defform[(on-disconnect dis-expr) + #:contracts + ([dis-expr (-> (unsyntax @tech{Universe}) world? bundle?)])]{ tell DrScheme to invoke @scheme[dis-expr] every time a participating @tech{world} drops its connection to the server. The first argument is the current state of the universe; the second one is the world that got @@ -1046,8 +1066,9 @@ optional handlers: } @item{ - @defform[(to-string - [render-expr (-> (unsyntax @tech{Universe}) string?)])]{ + @defform[(to-string render-expr) + #:contracts + ([render-expr (-> (unsyntax @tech{Universe}) string?)])]{ tell DrScheme to render the state of the universe after each event and to display this string in the universe console. }