Module Cf_gadget

module Cf_gadget: sig .. end
Monadic composition of complex stream processors. An experimental interface for constructing interactive functional systems in a single thread of control.


Overview

This module implements a marginally more general version of the Gadget system described in Chapter 30 of Magnus Carlsson's and Thomas Hallgren's joint Ph.D. thesis.

In the context of this module, a "gadget" is a monad that evaluates into a Cf_flow object, capable of alternately reading from a source of input values and writing to a sink of output values. The continuation monad is specialized over an abstract "work" monad type, and a scheduler handles the calls and jumps between multiple simultaneous work units, communicating with one another over a very lightweight message passing abstraction called a "wire".

The abstract work monad is a kind of state-continuation monad for operations over the internal Cf_flow value. The operations it supports are lifted into the gadget monad, and they are summarized as follows:

A wire is logically composed of a receiver and a transmitter, with weak mutual references between them. When either end of the wire is reclaimed by the memory allocator, the other end is automatically rendered into a null wire, i.e. receivers never get messages and transmitters put messages by discarding them.

A pair of classes are provided to represent the receiver and the transmitter on a wire. Objects of the rx class define a get method for creating a "gate" that can receive a message. Objects of the tx class define a put method for transmitting a message. Both objects can be constructed with a wire object, and a convenience operators are defined for creating a new wire and construction a pair of associated rx and tx objects.

Any gadget may read from the internal input stream or write to the external output stream. Conventionally, it is often simpler to define a a reader gadget and a writer gadget to localize these effects.

Note: see Magnus Carlsson's and Thomas Hallgren's joint Ph.D. thesis for a complete dissertation on the nature of the system of concepts behind this module.

Types

type ('i, 'o) work 
An functionally compositional work unit in a gadget, encapsulating the state-continuation monad for the underlying Cf_flow object.
type ('i, 'o) gate 
A gating sequence for receiving messages using the guard function.
type ('x, 'i, 'o) wire 
An object capable of delivering messages of type 'x from a sender to a a receiver in a ('i, 'o) work continuation.
type ('i, 'o, 'a) guard = (('i, 'o) gate, 'a) Cf_cmonad.t 
A guard for receiving a message from one or more sources.
type ('i, 'o, 'a) t = (('i, 'o) work, 'a) Cf_cmonad.t 
A continuation monad parameterized by work unit type.

Functions

val eval : ('i, 'o, unit) t -> ('i, 'o) Cf_flow.t
Use eval y to obtain a new flow by evaluating the gadget monad y.
val start : ('i, 'o, unit) t -> ('i, 'o, unit) t
Use start y to start a new gadget evaluating the gadget y.
val guard : ('i, 'o, unit) guard -> ('i, 'o, 'a) t
Use guard m to receive the next message guarded by m. The continuation bound to the result is discarded and control passes to the scheduler.
val abort : ('i, 'o, 'a) t
Use abort to abort gadgeting and return to the scheduler. This is a convenient shortcut for guard Cf_cmonad.nil.
val wire : ('i, 'o, ('x, 'i, 'o) wire) t
Use wire to return a new wire for carrying messages of type 'x.
val wirepair : ('i, 'o, ('x, 'i, 'o) wire * ('y, 'i, 'o) wire)
t
Use wirepair to return a pair of new wires for carrying messages of type 'x and 'y.
val null : ('i, 'o, ('x, 'i, 'o) wire) t
Use null to construct a wire that discards every message transmitted without ever delivering it. Such wires can be useful for default arguments to some gadget functions.
val read : ('i, 'o, 'i) t
Bind read to get the next input value from the external stream.
val write : 'o -> ('i, 'o, unit) t
Bind the result of write obj to put the next output value into the external stream.

Classes

class type connector = object .. end
The class type of connector objects.
class [['x, 'i, 'o]] rx : ('x, 'i, 'o) wire -> object .. end
The class of receiver objects.
class [['x, 'i, 'o]] tx : ('x, 'i, 'o) wire -> object .. end
The class of transmitter objects.

Miscellaneous

val connect : ('i, 'o, ('x, 'i, 'o) wire) t ->
('i, 'o, ('x, 'i, 'o) rx * ('x, 'i, 'o) tx) t
Use connect m to construct a new matching pair of rx and tx objects from the wire returned by m.
val simplex : ('i, 'o, ('x, 'i, 'o) rx * ('x, 'i, 'o) tx) t
Use simplex to construct a new matching pair of rx and tx objects. This is a convenient abbreviation of connect wire.
type ('x, 'y, 'i, 'o) pad = ('x, 'i, 'o) rx * ('y, 'i, 'o) tx 
A pair of convenience types for representing each end of a bundle of two wires used for duplex communication. By convention, a pad comprises a receiver for control events and a transmitter for notification events, and a fix comprises the transmitter for control events and the receiver for notification events
type ('x, 'y, 'i, 'o) fix = ('y, 'i, 'o) rx * ('x, 'i, 'o) tx 
val connectpair : ('i, 'o, ('x, 'i, 'o) wire * ('y, 'i, 'o) wire)
t ->
('i, 'o, ('x, 'y, 'i, 'o) fix * ('x, 'y, 'i, 'o) pad)
t
Use connectpair m to construct a new duplex communication channel, composed with the wire pair returned by m. A matching fix and pad of the channel are returned.
val duplex : ('i, 'o, ('x, 'y, 'i, 'o) fix * ('x, 'y, 'i, 'o) pad)
t
Use duplex to construct a new duplex communication channel, composed of two wires each in opposite flow. A matching fix and pad for each channel are returned. This is a convenient abbreviation of connectpair wirepair.
val wrap : ('x, 'i, 'o) #rx ->
('y, 'i, 'o) #tx ->
('x, 'y) Cf_flow.t -> ('i, 'o, unit) t
Use wrap rx tx w to start a new gadget that wraps the flow w, so that it reads output from the flow (copying it to tx object) and writes input to the flow (copying it from the rx object).
class virtual [['i, 'o]] next : object .. end
Use inherit ['i, 'o] next to derive a class that implements an intermediate state in a machine.
class virtual [['i, 'o]] start : object .. end
Use inherit ['i, 'o] start to derive a class to represent the initial state of a machine.
val create : (('c, 'n, 'i, 'o) pad -> ('i, 'o) #start) ->
('i, 'o, ('c, 'n, 'i, 'o) fix) t
Use create f to create a duplex channel, and apply f to the resulting pad to obtain the initial state of a machine. The machine is started and the corresponding fix is returned.
val createM : (('c, 'n, 'i, 'o) pad ->
('i, 'o, ('i, 'o) #start) t) ->
('i, 'o, ('c, 'n, 'i, 'o) fix) t
Use createM f to create a duplex channel, and apply f to the resulting pad to obtain a continuation monad that evaluates to the initial state of a machine. The machine is started and the corresponding fix is returned.