SPLAT documentation - chapter 5
Possibly useful data types and methods

5.1 <splat>

The <splat> data type is a structure that contains information about an instantiated splat, returned from the instantiation function. Most of the methods of this class are only used by the thread controlling splt execution, or by the various special syntax forms. However, some methods are directly useful to the splat writer.

5.1.1 (finish (self <splat>) return-code)

This method instructs a splat to stop executing immediately, terminate any active children, and set its return code to return-code. If the splat self refers to the splat in which the call takes place (i.e. the splat is finishing itself) termination takes place immediately. If the splat to finish is other than the current splat, the target does not terminate until its next call to check-completion, wait-for-pred, wait-for-task, or wait-forever. All splats which contain looping constructs should call check-completion on every iteration if possible.

finish circumvents the normal method-retrying routine. Regardless of the return-code, no further methods will be selected after finish is called on a splat.

5.1.2 (method-finish (self <splat>) return-code)

method-finish behaves like finish, except that if the return-code is not 'method-succeeded another method is still selected by the normal method.

5.1.3 (check-completion (self <splat>))

check-completion is the synchronization point for splat cancellation. It must be called periodically to allow parents or other splats to terminate a task. If another splat has called finish or method-finish on self, check-completion will not return. It invokes a continuation, saved before the selected method is run, to escape the method.

5.1.4 (start-task (child <splat>) (parent <splat>))

start-task runs a child splat (as returned from an instantiation function) under the control of the specified parent. To run a splat from the top-level read-eval-print loop, use #f for parent.

5.1.5 (wait-for-task (child <splat>) (parent <splat>))

wait-for-task blocks the parent splat until the child finishes. The value returned is the child's return code.

5.1.6 (run-top-level (child <splat>))

run-top-level is shorthand for starting and waiting for a task with parent set to #f. It blocks until the child finished.

5.1.7 (run (self <splat>))

run is like run-top-level, except that it can only be used within the body of a splat to run a child of the current splat.

5.1.8 (sequence-actions a1 a2 ... an)

sequence-actions is a special form which builds a temporary splat with one method which launches and waits for the splats a1 ... an in sequential order. If any of the splats fail, the sequence is short-circuited.

Like any other splat, the one returned from sequence-actions must be run with run, start-task, or equivalent.

5.1.9 (parallel-actions a1 a2 ... an)

parallel-actions is a special form which builds a temporary splat with one method which launches all splats a1 ... an and then waits for all of them to finish. If any of the splats fails, the sequence is aborted.

Like sequence-actions, parallel-actions returns a splat that must be run. Note that both sequence-actions and parallel-actions launch and wait for all their children, so when calls to these forms are nested (which is perfectly acceptable) only the top-most form needs to be explicitly run. In this example, the floor mopping and table cleaning can be done in parallel, but the table can't be wiped until the glass is picked up:

(define-splat (clean-up-spilled-milk (mop <cleaning-tool>) 
                                     (rag <cleaning-tool>))
  (method #t
          (wipe-feet rag)
          (mop-floor mop))
           (wipe-table rag)))))

This idiom allows the construction of arbitrarily-sequenced parallel and sequential actions.

5.1.10 (wait-for-pred (self <splat>) fluent-list pred)

wait-for-pred can be called within a method to block the splat until the predicate thunk pred on fluents fluent-list is true. This is a wrapper around a <splat-predicated-action>. See the <splat-fluent> documentation in <splat-fluent> and <splat-predicated-action> , section 5.3 for information on fluents and predicated actions.

5.1.11 (wait-forever (self <splat>))

wait-forever is a wrapper around wait-for-pred with a predicate of (lambda () #f). This function can be used when waiting for an event handler to be triggered by an external event.

5.2 <splat-behavior>

The <splat-behavior> is a close relative of the <splat> specialized for continuous closed-loop control laws rather than discrete actions.

5.2.1 (enable (behav <splat-behavior>))

enable causes a thread to be created which runs the function defined in the control portion of the define-behavior form. This thread must periodically call check-for-disable.

5.2.2 (disable (behav <splat-behavior>))

disable sets a flag which causes the behavior to exit the next time it calls check-for-disable. After the thread leaves the control function, the disable function (defined in the define-behavior form) is called.

5.2.3 (check-for-disable (self <splat-behavior>))

check-for-disable checks for the flag set by a call to disable and, if it is set, invokes a continuation saved before the thread was launched.

5.3 <splat-fluent> and <splat-predicated-action>

The <splat-fluent> class, together with the <splat-predicated-action> class, provides a basic synchronization mechanism for splats. A predicated action is a form of "callback" which has a predicate and a consequent. When the predicate becomes true, the consequent is evaluated.

The only way to avoid polling is somehow to be aware of any operation that could cause the predicate to become true and test the predicate when they change. We handle this by tagging each predicate thunk with a list of all the variables that can be changed externally to alter its truth value, and then wrapping access to those variables in functions that keep pointers to all the predicated actions that depend on those variables.

The wrapped variable is of type <splat-fluent>, and a combination of predicate, consequent, and a list of fluents is a <splat-predicated-action>. Predicated actions are used for the wait-for and event-handler portions of a splat definition, and by the wait-for-pred function.

5.3.1 (make <splat-fluent>)

splat-fluent objects have two slots that are accessible at creation time via keywords.

The initial value given to the fluent.

An equivalence predicate for the type of data to be stored in the fluent.

Neither keyword argument is mandatory. If no equiv-thunk is specified, predicates for actions that depend on the fluent are evaluated every time the set-fluent! method is called. If an equiv-thunk is specified, the predicates are only tested if the equiv-thunk returns false for a comparison of the old value of the fluent and the new one specified by set-fluent!.

5.3.2 (make <splat-predicated-action>)

splat-predicated-action objects have three mandatory keyword arguments to their constructor:

A function of one argument (of type <splat-predicated-action>) which returns #t if the consequent should be evaluated and #f otherwise.

A function of one argument (of type <splat-predicated-action>) which is run when the redicate becomes true.

A list of objects of type <splat-fluent> which should cause the predicate to be evaluated when changed.

The default behavior is one-shot. The action is only invoked once, and future #f--#t transitions of the predicate will not cause the action to be invoked. If repeated behavior is desired, call the enable method from within the action thunk.

5.3.3 (set-fluent! (fluent <splat-fluent>) value)

set-fluent! binds the fluent's value slot to value. This method is responsible for evaluating any predicates of predicated actions which depend on the fluent, and running the consequent of any predicates which become true. As such, there can be a not-insignificant time cost for invoking set-fluent!. Any number of predicate and consequent thunks for various predicated actions could conceivably be executed before the setter returns.

5.3.4 (get-fluent (fluent <splat-fluent>) value)

get-fluent is the getter method, which fetches the value of the fluent under mutex protection.

5.3.5 (enable (action <splat-predicated-action>))

enable installs handlers that allow fluents to check the predicate when they change. A predicated action must be enabled to have a chance to run its action. They are not enabled on creation, and must be re-enabled in the action-thunk if one-shot behavior is not desired.

5.3.6 (disable (action <splat-predicated-action>))

disable is the opposite of enable, removing the action from the notify list of the relevant fluents.
SPLAT documentation - Copyright 1996-1997 Bill Gribble.
Contents; back.
2 September 1997
Bill Gribble grib@cs.utexas.edu