(define-splat (name . args) .
body)
is a Scheme special form. Arguments are not
evaluated in the normal way, and the body of the form can contain only
a small set of recognized sub-forms. This section describes the
recognized parts of a define-splat form. The general form of the
syntax is:
(define-splat (name arg1 arg2 ... argn) (local-vars (var1 value1) (var2 value2) ... (varn valuen)) (preconditions . body) (initializer . body) (finalizer . body) (wait-for fluent-list . body) (event-handler (event predicate) (action action) (method context . body))
The wait-for
, event-handler
, and method
forms can be repeated as necessary to describe all of the relevant
parts. Any of the parts except the initial (name
. args)
binding form can be omitted, and parts can appear in
any order.
(name . args)
(name . args)
binding form. This has exactly
the same syntax as the (name . args)
part of the
(define (name . args) . body)
function
definition shortcut, including typing of arguments. The arguments are
in scope throughout the define-splat form.
The symbol name is bound to a function which has the argument
signature specified in the binding form. This function returns a data
structure of type <splat> which can be thought of as a handle or
process structure connected to an active task of the type defined by
the define-splat form. Within the body of the define-splat form, this
structure can be referred to by the variable self
, which is
in scope everywhere in the body of the define-splat form. Invoking
the function defined by define-splat
does not start execution
of the task; this must be done by a call to run
,
run-top-level
or start-task
.
(local-vars (arg val) ...)
The syntax of the variable binding forms is identical to that of the
binding forms of a normal let*
form. Not surprisingly, the
local-vars
form expands a let*
internally, which
means that the variable binding forms are evaluated at the time that
the splat instantiation function (the procedure bound to name
by the define-splat
form) is called.
(preconditions . body)
(and ...)
. All must all be true
for the SPLAT to run. If any of the precondition predicates return
#f, the SPLAT fails without a method being selected, and the return
value (return-value splat) returning 'precond-failed.
(initializer . body)
(finalizer . body)
(wait-for fluent-list . body)
splat-fluent
objects referred to in the
body predicate. The predicate form is evaluated only when
one or more of these fluents changes in value. See the
splat-predicated-action
description in
<splat-fluent>
and <splat-predicated-action>
, section 5.3 for more details.
(event-handler (event fluent-list . body)
(action . body))
(method context . body)
The value that a method returns determines the action taken by the
splat engine. If the value is 'method-succeeded
, the method
is considered to have succeeded and the splat invokes finalizers and
exits. If a method returns any other value, another method is
selected and run if a relevant one can be found. If no other relevant
method can be found, the splat engine runs finalizers and exits.
The fate of a splat can be found by the
(return-code splat)
. This is set to the value
returned from a selected method, or another value reflecting the
reason the splat finished. Meaningful values for the return code are:
'method-succeeded
'no-method
'failed-precond
(method-finish splat retval)
immediately returns from the method with the
specified return value. If retval is not
'method-succeeded
, another method is selected. (finish
splat retval)
causes the splat to exit
absolutely with the specified return code, not selecting another
method regardless of the value of retval.