changed docs for universe

svn: r15094
This commit is contained in:
Matthias Felleisen 2009-06-05 15:39:04 +00:00
parent f04f42db76
commit 55ee0f126b

View File

@ -1014,19 +1014,18 @@ for universe programs. For example:
} }
@item{Each event handler produces a @emph{bundle}, which is a structure @item{Each event handler produces a @emph{bundle}, which is a structure
that contains the list of @emph{iworld}s that the universe must track; the that contains the @tech{server}'s state, a list of mails to other worlds,
@tech{server}'s remaining state; and a list of mails to other and the list of @emph{iworld}s that are to be disconnected.
worlds:
@defproc[(bundle? [x any/c]) boolean?]{ @defproc[(bundle? [x any/c]) boolean?]{
determines whether @scheme[x] is a @emph{bundle}.} determines whether @scheme[x] is a @emph{bundle}.}
@defproc[(make-bundle [low (listof iworld?)] [state any/c] [mails (listof mail?)]) bundle?]{ @defproc[(make-bundle [state any/c] [mails (listof mail?)] [low (listof iworld?)]) bundle?]{
creates a @emph{bundle} from a list of iworlds, a piece of data that creates a @emph{bundle} from a piece of data that
represents a server state, and a list of mails.} represents a server state, a list of mails, and a list of iworlds.}
If an event handler returns a bundle with an empty list of worlds, the If disconnecting from these worlds results in an empty list of
universe server is restarted in the initial state. participants, the universe server is restarted in the initial state.
A @emph{mail} represents a message from an event handler to a world. The A @emph{mail} represents a message from an event handler to a world. The
teachpack provides only a predicate and a constructor for these structures: teachpack provides only a predicate and a constructor for these structures:
@ -1095,31 +1094,28 @@ The mandatory clauses of a @scheme[universe] server description are
@item{ @item{
@defform[(on-new new-expr) @defform[(on-new new-expr)
#:contracts #:contracts
([new-expr (-> [listof iworld?] (unsyntax @tech{UniverseState}) iworld? bundle?)])]{ ([new-expr (-> (unsyntax @tech{UniverseState}) iworld? bundle?)])]{
tell DrScheme to call the function @scheme[new-expr] every time another world joins the tell DrScheme to call the function @scheme[new-expr] every time another world joins the
universe. The event handler is called on the current list of iworlds and the universe. The event handler is called with the current state and the
joining iworld, which isn't on the list yet. In particular, the handler may joining iworld, which isn't on the list yet. In particular, the handler may
reject a @tech{world} program from participating in a @tech{universe}, reject a @tech{world} program from participating in a @tech{universe},
simply by not including it in the resulting @scheme[bundle] structure. The by simply including it in the resulting @scheme[bundle] structure (third field).}
handler may still send one message to the world that attempts to join. }
} }
@item{ @item{
@defform[(on-msg msg-expr) @defform[(on-msg msg-expr)
#:contracts #:contracts
([msg-expr (-> [listof iworld?] (unsyntax @tech{UniverseState}) iworld? sexp? bundle?)])]{ ([msg-expr (-> (unsyntax @tech{UniverseState}) iworld? sexp? bundle?)])]{
tell DrScheme to apply @scheme[msg-expr] to the current state of the universe, the world
tell DrScheme to apply @scheme[msg-expr] to the list of currently
participating worlds @scheme[low], the current state of the universe, the world
@scheme[w] that sent the message, and the message itself. Note that @scheme[w] that sent the message, and the message itself. Note that
@scheme[w] is guaranteed to be on the list @scheme[low]. @scheme[w] is guaranteed to be on the list @scheme[low].
} }
}] }]
All proper event handlers produce a @emph{bundle}. The list of worlds in All proper event handlers produce a @emph{bundle}. The state in the
this @emph{bundle} becomes the server's list of worlds, meaning that only bundle is safe-guarded by the server until the next event, and the mails
the server listens only to messages from "approved" worlds. The state in are broadcast as specified. The list of iworlds in the third field of the
the bundle is safe-guarded by the server until the next event, and the bundle is removed from the list of participants from which to expect
mails are broadcast as specified. messages.
The following picture provides a graphical overview of the server's workings. The following picture provides a graphical overview of the server's workings.
@ -1137,7 +1133,7 @@ optional handlers:
@item{ @item{
@defform/none[(on-tick tick-expr) @defform/none[(on-tick tick-expr)
#:contracts #:contracts
([tick-expr (-> [listof iworld?] (unsyntax @tech{UniverseState}) bundle?)])]{ ([tick-expr (-> (unsyntax @tech{UniverseState}) bundle?)])]{
tell DrScheme to apply @scheme[tick-expr] to the current list of tell DrScheme to apply @scheme[tick-expr] to the current list of
participating worlds and the current state of the participating worlds and the current state of the
universe. universe.
@ -1145,7 +1141,7 @@ optional handlers:
@defform/none[(on-tick tick-expr rate-expr) @defform/none[(on-tick tick-expr rate-expr)
#:contracts #:contracts
([tick-expr (-> [listof iworld?] (unsyntax @tech{UniverseState}) bundle?)] ([tick-expr (-> (unsyntax @tech{UniverseState}) bundle?)]
[rate-expr natural-number/c])]{ [rate-expr natural-number/c])]{
tell DrScheme to apply @scheme[tick-expr] as above but use the specified tell DrScheme to apply @scheme[tick-expr] as above but use the specified
clock tick rate instead of the default. clock tick rate instead of the default.
@ -1156,7 +1152,7 @@ optional handlers:
@item{ @item{
@defform[(on-disconnect dis-expr) @defform[(on-disconnect dis-expr)
#:contracts #:contracts
([dis-expr (-> [listof iworld?] (unsyntax @tech{UniverseState}) iworld? bundle?)])]{ ([dis-expr (-> (unsyntax @tech{UniverseState}) iworld? bundle?)])]{
tell DrScheme to invoke @scheme[dis-expr] every time a participating tell DrScheme to invoke @scheme[dis-expr] every time a participating
@tech{world} drops its connection to the server. The first two arguments @tech{world} drops its connection to the server. The first two arguments
are the current list of participating worlds and the state of the are the current list of participating worlds and the state of the
@ -1167,7 +1163,7 @@ optional handlers:
@item{ @item{
@defform[(to-string render-expr) @defform[(to-string render-expr)
#:contracts #:contracts
([render-expr (-> [listof iworld?] (unsyntax @tech{UniverseState}) string?)])]{ ([render-expr (-> (unsyntax @tech{UniverseState}) string?)])]{
tell DrScheme to render the state of the universe after each event and to tell DrScheme to render the state of the universe after each event and to
display this string in the universe console. display this string in the universe console.
} }
@ -1294,16 +1290,16 @@ translates into the design of two functions with the following headers,
#reader scribble/comment-reader #reader scribble/comment-reader
(schemeblock (schemeblock
;; Bundle is ;; Bundle is
;; (make-bundle [Listof iworld?] UniverseState [Listof mail?]) ;; (make-bundle UniverseState [Listof mail?] [Listof iworld?])
;; [Listof iworld?] UniverseState iworld? -> Bundle ;; UniverseState iworld? -> Bundle
;; compute next list of worlds and new @tech{UniverseState} ;; next list of worlds when world w is joining
;; when world w is joining the universe, which is in state s; ;; the universe in state s
(define (add-world s w) ...) (define (add-world s w) ...)
;; [Listof iworld?] UniverseState iworld? W2U -> Bundle ;; UniverseState iworld? W2U -> Bundle
;; compute next list of worlds and new @tech{UniverseState} ;; next list of worlds when world w is sending message m to
;; when world w is sending message m to universe in state s ;; the universe in state s
(define (process s p m) ...) (define (process s p m) ...)
)) ))
@ -1419,13 +1415,13 @@ The preceding subsection dictates that our server program starts like this:
#reader scribble/comment-reader #reader scribble/comment-reader
[schemeblock [schemeblock
;; Result is ;; Result is
;; (make-bundle [Listof world?] '* (list (make-mail world? GoMessage))) ;; (make-bundle [Listof iworld?] (list (make-mail iworld? GoMessage)) '())
;; [Listof world?] UniverseState world? -> Result ;; [Listof iworld?] iworld? -> Result
;; add world w to the universe, when server is in state u ;; add world w to the universe, when server is in state u
(define (add-world u w) ...) (define (add-world u w) ...)
;; [Listof world?] UniverseState world? StopMessage -> Result ;; [Listof iworld?] iworld? StopMessage -> Result
;; world w sent message m when server is in state u ;; world w sent message m when server is in state u
(define (switch u w m) ...) (define (switch u w m) ...)
]) ])
@ -1443,17 +1439,17 @@ The second step of the design recipe calls for functional examples:
[schemeblock [schemeblock
;; an obvious example for adding a world: ;; an obvious example for adding a world:
(check-expect (check-expect
(add-world '() '* world1) (add-world '() world1)
(make-bundle (list world1) (make-bundle (list world1)
'* (list (make-mail world1 'it-is-your-turn))
(list (make-mail world1 'it-is-your-turn)))) '()))
;; an example for receiving a message from the active world: ;; an example for receiving a message from the active world:
(check-expect (check-expect
(switch (list world1 world2) '* world1 'done) (switch (list world1 world2) world1 'done)
(make-bundle (list world2 world1) (make-bundle (list world2 world1)
'* (list (make-mail world2 'it-is-your-turn))
(list (make-mail world2 'it-is-your-turn)))) '()))
]) ])
Note that our protocol analysis dictates this behavior for the two Note that our protocol analysis dictates this behavior for the two
@ -1475,8 +1471,8 @@ The protocol tells us that @emph{add-world} just adds the given
(define (add-world univ state wrld) (define (add-world univ state wrld)
(local ((define univ* (append univ (list wrld)))) (local ((define univ* (append univ (list wrld))))
(make-bundle univ* (make-bundle univ*
'* (list (make-mail (first univ*) 'it-is-your-turn))
(list (make-mail (first univ*) 'it-is-your-turn))))) '())))
]) ])
Because @emph{univ*} contains at least @emph{wrld}, it is acceptable to Because @emph{univ*} contains at least @emph{wrld}, it is acceptable to
@ -1492,11 +1488,11 @@ Similarly, the protocol says that when @emph{switch} is invoked because a
@(begin @(begin
#reader scribble/comment-reader #reader scribble/comment-reader
[schemeblock [schemeblock
(define (switch univ state wrld m) (define (switch univ wrld m)
(local ((define univ* (append (rest univ) (list (first univ))))) (local ((define univ* (append (rest univ) (list (first univ)))))
(make-bundle univ* (make-bundle univ*
'* (list (make-mail (first univ*) 'it-is-your-turn))
(list (make-mail (first univ*) 'it-is-your-turn))))) '())))
]) ])
As before, appending the first world to the end of the list guarantees As before, appending the first world to the end of the list guarantees
@ -1505,7 +1501,7 @@ Similarly, the protocol says that when @emph{switch} is invoked because a
Start the server now. Start the server now.
@schemeblock[(universe '* (on-new add-world) (on-msg switch))] @schemeblock[(universe '() (on-new add-world) (on-msg switch))]
Exercise: The function definition simply assumes that @emph{wrld} is Exercise: The function definition simply assumes that @emph{wrld} is
@scheme[world=?] to @scheme[(first univ)] and that the received message @scheme[world=?] to @scheme[(first univ)] and that the received message