From 391243e3cb57900d81bc223673ad9d15958174f2 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Wed, 6 Aug 2014 17:20:42 -0700 Subject: [PATCH] Initial hacking on the documentation to make it untyped only. --- scribblings/concepts.scrbl | 5 +- scribblings/drivers.scrbl | 27 +-- scribblings/highlevel.scrbl | 184 +++++++------------- scribblings/lowlevel.scrbl | 2 +- scribblings/management-and-monitoring.scrbl | 3 +- 5 files changed, 74 insertions(+), 147 deletions(-) diff --git a/scribblings/concepts.scrbl b/scribblings/concepts.scrbl index 9795afd..ceaaa02 100644 --- a/scribblings/concepts.scrbl +++ b/scribblings/concepts.scrbl @@ -82,8 +82,9 @@ actions the process wishes to perform. See @secref{Actions} for the possible actions a process can take. Note that the result of an event handler function is actually a -@racket[Transition] structure; the actual Typed Racket type of event -handlers is @racket[TrapK], defined in @secref{handler-functions}. +@racket[transition] structure containing a new state and a sequence of +actions, rather than the explicit pair shown in the approximate type +above. See @secref{handler-functions} for more on handler functions. @section{What is a VM?} diff --git a/scribblings/drivers.scrbl b/scribblings/drivers.scrbl index 04cbbb1..3015f04 100644 --- a/scribblings/drivers.scrbl +++ b/scribblings/drivers.scrbl @@ -34,10 +34,9 @@ the subscription at the meta-level as well. @defmodule[marketplace/drivers/tcp-bare]{ -This module is only available for use by untyped Racket processes. It -is included by default in programs using @tt{#lang marketplace}; see -@secref{hashlang-variations} for information on other language -variants. +This module is included by default in programs using @tt{#lang +marketplace}; see @secref{hashlang-variations} for information on +other language variants. @defproc[(tcp-driver) Spawn]{ @@ -57,9 +56,9 @@ A pre-made @racket[spawn] action equivalent to @racket[(tcp-driver)]. @subsection{TCP channels} -@defstruct*[tcp-channel ([source TcpAddress] - [destination TcpAddress] - [subpacket TcpSubPacket]) #:prefab]{ +@defstruct*[tcp-channel ([source (or/c tcp-address? tcp-handle? tcp-listener?)] + [destination (or/c tcp-address? tcp-handle? tcp-listener?)] + [subpacket (or/c eof-object? bytes?)]) #:prefab]{ A TCP channel represents a section of a unidirectional TCP flow appearing on our local "subnet" of the full TCP network, complete with @@ -67,10 +66,6 @@ source, destination and subpacket. Each TCP connection has two such flows: one inbound (remote-to-local) bytestream, and one outbound (local-to-remote) bytestream. -} - -@deftype[TcpSubPacket (or/c eof-object? bytes?)]{ - Packets carried by @racket[tcp-channel] structures are either end-of-file objects or raw binary data represented as Racket byte vectors. @@ -79,8 +74,6 @@ vectors. @subsection{TCP addresses} -@deftype[TcpAddress (or/c tcp-address? tcp-handle? tcp-listener?)]{ - A TCP address describes one end of a TCP connection. It can be either @itemlist[ @@ -89,8 +82,6 @@ A TCP address describes one end of a TCP connection. It can be either @item{a @racket[tcp-listener], representing a local socket on a user-assigned port.} ] -} - @defstruct*[tcp-address ([host string?] [port (integer-in 0 65535)]) #:prefab]{ @@ -109,7 +100,7 @@ a local name for whichever underlying port number ends up being used. The @racket[id] must be chosen carefully: it is scoped to the local VM, i.e. shared between processes in that VM, so processes must make sure not to accidentally clash in handle ID selection. They are also -used in TcpChannel to mean a specific @emph{instance} of a TCP +used in @racket[tcp-channel] to mean a specific @emph{instance} of a TCP connection, so if you are likely to want to reconnect individual flows, use different values for @racket[id]. @@ -203,14 +194,14 @@ where, as for receiving data, the @racket[subpacket] is either Not yet documented. } -@section{timer (typed and untyped)} +@section{timer} For examples of the use of the timer driver, see uses of @racket[set-timer] and @racket[timer-expired] in @hyperlink["https://github.com/tonyg/marketplace-dns/blob/master/network-query.rkt"]{the Marketplace-based DNS resolver}. -@section{udp (typed and untyped)} +@section{udp} For examples of the use of the UDP driver, see uses of @racket[udp-packet] etc. in diff --git a/scribblings/highlevel.scrbl b/scribblings/highlevel.scrbl index abc6a82..d2d6cf0 100644 --- a/scribblings/highlevel.scrbl +++ b/scribblings/highlevel.scrbl @@ -15,9 +15,7 @@ interface} of a Unix-like operating system. @;{ @defmodulelang*[(marketplace - marketplace/flow-control - marketplace/typed - marketplace/typed/flow-control)] + marketplace/flow-control)] } @defmodulelang[marketplace] @@ -31,28 +29,19 @@ actions spawn application processes and nested VMs, which in turn subscribe to sources of events from the outside world. At present, there's just @tt{#lang marketplace}. In future, there will -be a variation for Typed Racket, and languages providing greater -support for flow control, responsibility transfer, and other -networking concepts. For now, Typed Racket programs must be written as -@tt{#lang typed/racket} programs using @racket[(require marketplace)] -and @racket[ground-vm:] explicitly. +be languages providing greater support for flow control, +responsibility transfer, and other networking concepts. @;{ @itemlist[ - @item{@racket[marketplace] is for @emph{untyped} programs, and uses + @item{@racket[marketplace] is for ordinary Racket programs, and uses the @secref{tcp-bare} TCP driver;} @item{@racket[marketplace/flow-control] is like @racket[marketplace], but uses the flow-controlled @secref{tcp} driver;} - @item{@racket[marketplace/typed] is like @racket[marketplace], but - for @emph{typed} programs;} - - @item{@racket[marketplace/typed/flow-control] is like - @racket[marketplace/flow-control], but for typed programs.} - ] } @@ -65,7 +54,7 @@ Instead of using Racket's @tt{#lang} feature, ordinary Racket programs can use Marketplace features by requiring Marketplace modules directly. -Such programs need to use @racket[ground-vm]/@racket[ground-vm:] to +Such programs need to use @racket[ground-vm] to start the ground-level VM explicitly. They also need to explicitly start any drivers they need; for example, the file @filepath{examples/echo-plain.rkt} uses @racket[ground-vm] along with @@ -78,27 +67,20 @@ start any drivers they need; for example, the file (on-presence (spawn (echoer from to)))))) ] -@deftogether[( -@defform[(ground-vm maybe-boot-pid-binding maybe-initial-state initial-action ...)] -@defform[(ground-vm: maybe-boot-pid-binding maybe-typed-initial-state initial-action ...) +@defform[(ground-vm maybe-boot-pid-binding maybe-initial-state initial-action ...) #:grammar [(maybe-boot-pid-binding (code:line) (code:line #:boot-pid id)) (maybe-initial-state (code:line) (code:line #:initial-state expr)) - (maybe-typed-initial-state (code:line) - (code:line #:initial-state expr : type)) - (initial-action expr)]] -)]{ + (initial-action expr)]]{ -Starts the ground VM, in untyped and typed programs, respectively. If -@racket[#:boot-pid] is specified, the given identifier is bound within -the form to the PID of the @emph{primordial process} that performs the -initial actions. If @racket[#:initial-state] is specified (with a -type, for @racket[ground-vm:]), it is used as the initial state for -the primordial process; if it is not supplied, the primordial process -is given @racket[(void)] as its initial state (and @racket[Void] as -its state type). +Starts the ground VM. If @racket[#:boot-pid] is specified, the given +identifier is bound within the form to the PID of the @emph{primordial +process} that performs the initial actions. If +@racket[#:initial-state] is specified, it is used as the initial state +for the primordial process; if it is not supplied, the primordial +process is given @racket[(void)] as its initial state. } @@ -109,32 +91,24 @@ its state type). @deftogether[( @defform[(transition new-state action-tree ...)] -@defform[(transition: new-state : State action-tree ...)] @defform[(transition/no-state action-tree ...)] )]{ -Each of these forms produces a @racket[Transition] structure. The -first is for untyped code, the second for typed code (where the -mandatory @racket[State] is the type of the transitioning process's -private state), and the third for either. +Each of these forms produces a @racket[transition] structure. -Each @racket[action-tree] must be an @racket[(ActionTree State)]. - -It's fine to include @emph{no} action-trees, in which case the +Each @racket[action-tree] must be an @tech{action tree}. +It's fine to include @emph{no} action trees, in which case the transition merely updates the state of the process without taking any actions. -In the case of @racket[transition/no-state], the type @racket[Void] -and value @racket[(void)] is used for the process state. -@racket[transition/no-state] is useful for processes that are -stateless other than the implicit state of their endpoints. +In the case of @racket[transition/no-state], the value @racket[(void)] +is used for the process state. @racket[transition/no-state] is useful +for processes that are stateless other than the implicit state of +their endpoints. } -@deftogether[( -@defstruct*[transition ([state State] [actions (ActionTree State)]) #:transparent] -@deftype[(Transition State) (transition State)] -)]{ +@defstruct*[transition ([state State] [actions action-tree?]) #:transparent]{ A transition structure. The @racket[transition-state] field is the new private state the process will have after the transition is applied, @@ -143,16 +117,23 @@ performed by the VM in order to apply the transition. } -@deftogether[( -@deftype[(ActionTree State) (Constreeof (Action State))] -@deftype[(Constreeof X) (Rec CT (U X (Pairof CT CT) False Void Null))] -)]{ +@defproc[(action-tree? [value any/c]) boolean?]{ -An action-tree is a @deftech{cons-tree} of @racket[Action]s. When -performing actions, a VM will traverse an action-tree in left-to-right -order. +Predicate that recognises an @deftech{action tree}. An action tree is +either -@racket['()], @racket[(void)], and @racket[#f] may also be present in +@itemlist[ + @item{@racket['()];} + @item{@racket[#f];} + @item{@racket[(void)];} + @item{a pair of action trees; or} + @item{an @tech{action}.} +] + +When performing actions, a VM will traverse an action-tree in +left-to-right order. + +@racket['()], @racket[(void)], and @racket[#f] may be present in action-trees: when the VM reaches such a value, it ignores it and continues with the next leaf in the tree. @@ -194,10 +175,9 @@ at all" in a transition: } -@defproc[(sequence-actions [initial-transition (Transition State)] - [item (U (ActionTree State) - (State -> (Transition State)))] - ...) (Transition State)]{ +@defproc[(sequence-actions [initial-transition transition?] + [item (or/c action-tree? (any/c -> transition?))] + ...) transition?]{ Returns a transition formed from the @racket[initial-transition] extended with new actions, possibly updating its carried state. Each @@ -238,44 +218,30 @@ collection of macros helps streamline endpoint setup. @deftogether[( @defform[(publisher topic handler ...)] -@defform[(publisher: State topic handler ...)] @defform[(subscriber topic handler ...)] -@defform[(subscriber: State topic handler ...)] @defform[(observe-subscribers topic handler ...)] -@defform[(observe-subscribers: State topic handler ...)] @defform[(observe-publishers topic handler ...)] -@defform[(observe-publishers: State topic handler ...)] @defform[(observe-subscribers/everything topic handler ...)] -@defform[(observe-subscribers/everything: State topic handler ...)] @defform[(observe-publishers/everything topic handler ...)] -@defform[(observe-publishers/everything: State topic handler ...)] @defform[(build-endpoint pre-eid role handler ...)] -@defform[(build-endpoint: State pre-eid role handler ...)] )]{ The many variations on the core -@racket[build-endpoint]/@racket[build-endpoint:] form exist to give +@racket[build-endpoint] form exist to give good control over @racket[InterestType] in the endpoint under construction; see @secref{participating-vs-observing}. Almost everything is optional in an endpoint definition. The only -mandatory part is the topic, unless you're using Typed Racket, in -which case the process state type must also be specified. +mandatory part is the topic. For example, a minimal endpoint subscribing to all messages would be: @racketblock[(subscriber ?)] -or in Typed Racket, for a process with @racket[Integer] as its process -state type, - -@racketblock[(subscriber: Integer ?)] - A minimal publishing endpoint would be: -@racketblock[(publisher ?) - (publisher: Integer ?)] +@racketblock[(publisher ?)] While topic patterns are ordinary Racket data with embedded @racket[?] wildcards (see @secref{messages-and-topics}), all the other patterns @@ -313,7 +279,7 @@ the wrapped handlers are expected to return @seclink["constructing-transitions"]{transition structures}. If not, however, the handler expressions are expected to return plain -@racket[ActionTree]s. +@tech{action tree}s. This way, simple handlers that do not need to examine the process state, and simply act in response to whichever event triggered them, @@ -476,9 +442,8 @@ dynamically: @itemlist[ - @item{@racket[publisher] and @racket[subscriber] (and typed -variations ending in @tt{:}) are for ordinary @emph{participation} in -conversations;} + @item{@racket[publisher] and @racket[subscriber] are for ordinary +@emph{participation} in conversations;} @item{@racket[observe-subscribers] and @racket[observe-publishers] are for @emph{observing} conversations without participating in them; and} @@ -503,7 +468,7 @@ but as an observer, the code should declare the roles being observed. Endpoint names can be used to @seclink["updating-endpoints"]{update} or @seclink["deleting-endpoints"]{delete} endpoints. -@defproc[(name-endpoint [id Any] [add-endpoint-action AddEndpoint]) AddEndpoint]{ +@defproc[(name-endpoint [id any/c] [add-endpoint-action AddEndpoint]) AddEndpoint]{ Returns a copy of the passed-in @racket[add-endpoint] action structure, with the @racket[id] field set to the passed-in identifying @@ -565,15 +530,7 @@ Equivalent to @racket[(send-message body 'subscriber)]. @defform[(spawn maybe-pid-binding boot-expr)] @defform[(spawn/continue maybe-pid-binding #:parent parent-state-pattern k-expr - #:child boot-expr)] -@defform[#:literals (:) - (spawn: maybe-pid-binding - #:parent : ParentStateType - #:child : ChildStateType boot-expr)] -@defform[#:literals (:) - (spawn/continue: maybe-pid-binding - #:parent parent-state-pattern : ParentStateType k-expr - #:child : ChildStateType boot-expr) + #:child boot-expr) #:grammar [(maybe-pid-binding (code:line) (code:line #:pid identifier)) @@ -589,15 +546,11 @@ If @racket[#:pid] is supplied, the associated identifier is bound to the child process's PID in both @racket[boot-expr] and the parent's @racket[k-expr]. -The @racket[spawn/continue] and @racket[spawn/continue:] variations -include a @racket[k-expr], which will run in the parent process after -the child process has been created. Note that @racket[k-expr] must -return a @racket[Transition], since @racket[parent-state-pattern] is -always supplied for these variations. - -In Typed Racket, for type system reasons, @racket[spawn:] and -@racket[spawn/continue:] require @racket[ParentStateType] to be -supplied as well as @racket[ChildStateType]. +The @racket[spawn/continue] variation includes a @racket[k-expr], +which will run in the parent process after the child process has been +created. Note that @racket[k-expr] must return a @racket[transition], +since @racket[parent-state-pattern] is always supplied for these +variations. } @@ -634,11 +587,7 @@ itself. @section{Cooperative scheduling} -@deftogether[( -@defform[(yield state-pattern k-expr)] -@defform[#:literals (:) - (yield: state-pattern : State k-expr)] -)]{ +@defform[(yield state-pattern k-expr)]{ Lets other processes in the system run for a step, returning to evaluate @racket[k-expr] only after doing a complete round of the @@ -646,23 +595,16 @@ scheduler. The state of the yielding process will be matched against @racket[state-pattern] when the process is resumed, and -@racket[k-expr] must evaluate to a @racket[Transition]. +@racket[k-expr] must evaluate to a @racket[transition]. } @section{Creating nested VMs} -@deftogether[( @defform[(spawn-vm maybe-vm-pid-binding maybe-boot-pid-binding maybe-initial-state maybe-debug-name - boot-action-expr ...)] -@defform[#:literals (:) - (spawn-vm: : ParentStateType - maybe-vm-pid-binding maybe-boot-pid-binding - maybe-typed-initial-state - maybe-debug-name - boot-action-expr ...) + boot-action-expr ...) #:grammar [(maybe-vm-pid-binding (code:line) (code:line #:vm-pid identifier)) @@ -670,12 +612,9 @@ The state of the yielding process will be matched against (code:line #:boot-pid identifier)) (maybe-initial-state (code:line) (code:line #:initial-state expr)) - (maybe-typed-initial-state (code:line) - (code:line #:initial-state expr : StateType)) (maybe-debug-name (code:line) (code:line #:debug-name expr)) - (boot-action-expr expr)]] -)]{ + (boot-action-expr expr)]]{ Results in a @racket[spawn] action that starts a nested VM. The primordial process in the new VM executes the boot-actions with the @@ -692,10 +631,7 @@ primordial process in the new VM. @section{Relaying across layers} -@deftogether[( -@defform[(at-meta-level: StateType preaction ...)] -@defproc[(at-meta-level [preaction (PreAction State)] ...) (Action StateType)] -)]{ +@defproc[(at-meta-level [preaction (PreAction State)] ...) (Action StateType)]{ Each VM gives its processes access to two distinct IPC facilities: the @emph{internal} one, provided for the VM's processes to talk amongst @@ -704,9 +640,9 @@ itself is a process within. Marketplace's actions can apply to either of those two networks. By default, actions apply to the VM of the acting process directly, but -using @racket[at-meta-level] (or @racket[at-meta-level:] in typed -code) to wrap an action @emph{level-shifts} the action to make it -apply at the level of the acting process's VM's container instead. +using @racket[at-meta-level] to wrap an action @emph{level-shifts} the +action to make it apply at the level of the acting process's VM's +container instead. For example, wrapping an @racket[endpoint] in @racket[at-meta-level] adds a subscription to the VM's container's network. Instead of diff --git a/scribblings/lowlevel.scrbl b/scribblings/lowlevel.scrbl index ea6f041..031561f 100644 --- a/scribblings/lowlevel.scrbl +++ b/scribblings/lowlevel.scrbl @@ -20,7 +20,7 @@ interface} of a Unix-like operating system. Each @deftech{handler function} is always associated with a particular @tech{endpoint}, registered with the VM via -@racket[endpoint]/@racket[endpoint:]/@racket[add-endpoint]. A handler +@racket[endpoint]/@racket[add-endpoint]. A handler function for a given process with state type @racket[State] has type: @racketblock[(EndpointEvent -> State -> (Transition State))] diff --git a/scribblings/management-and-monitoring.scrbl b/scribblings/management-and-monitoring.scrbl index 5911717..a96aa44 100644 --- a/scribblings/management-and-monitoring.scrbl +++ b/scribblings/management-and-monitoring.scrbl @@ -28,8 +28,7 @@ each @racket['publisher] message sent to the VM's network. @section[#:tag "logging"]{logging (MARKETPLACE_LOG)} -@defmodule*[(marketplace/log-untyped - marketplace/log-typed)]{ +@defmodule*[(marketplace/log)]{ @defform[#:kind "environment variable" #:id MARKETPLACE_LOG MARKETPLACE_LOG]{