(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.