next up previous contents index
Next: Controlled Retrieval Up: Special Forms Previous: Calling Algernon from Lisp

Calling Lisp from Algernon

 

The special forms in this section allow a Lisp expression to be evaluated, and the value used in Algernon in various ways. Before an expression is evaluated in Lisp, any Algernon variables appearing in the expression are replaced by their bindings.

(:eval  expression)

Evaluates expression as a Lisp expression for side effects. Returned value is ignored. Thus one can print out the children of Tom using the path:

((child Tom ?x) (:eval (format t "A child of Tom is ~a.~%" '?x))).

(:test  expression)

Evaluates expression as a Lisp expression and succeeds iff it does not evaluate to nil.

(:boundp  variable)

Succeeds if variable is bound to a value (not another variable), and fails otherwise.

(:unboundp  variable)

Succeeds if variable is unbound, and fails otherwise.

(:funcall  function exp tex2html_wrap_inline1490 ...exp tex2html_wrap_inline1492 )

Applies function to the values obtained by evaluating exp tex2html_wrap_inline1490 ... exp tex2html_wrap_inline1492 . Each of the exp tex2html_wrap_inline1498 may be of one of four forms:

:assumptions  -- returns the list of lists of assumptions currently in force, in case the Lisp function needs them for something.
(:values  frame slot) -- evaluates to a list of the values stored in slot of frame, stripped of the associated assumptions.
(:non-values  frame slot) -- evaluates to a list of the explicit non-values in slot of frame, stripped of their associated assumptions.
otherwise -- evaluated as a Lisp expression.

When :funcall appears as a top-level special form in a path, the value returned is ignored by Algernon. However, :funcall  can also be embedded in :bind or :branch forms, in which case the value returned can be bound to Algernon variables.

(:bind  variable expression)
(:bind (variable tex2html_wrap_inline1330 ) expression)

After substituting in the values of any Algernon variables, evaluate the second argument and unify the result with the first argument. The expression may be a Lisp expression or an embedded :funcall expression. For example, to determine the number of values in a slot: (:bind ?n (:funcall #'length (:values frame slot)))

Because the variable argument is unified with the result of evaluating expression, :bind can be used to destructure and test properties of the value returned. For example, suppose the Lisp function (gossip) returns a list of the form (Tom loves Mary) or (Bill hates Joe) or some such. We could select for a particular case, and bind variables to the names of the protagonists with: (:bind (?subj loves ?obj) (gossip))

The value returned from the Lisp function is captured using multiple-value-bind, with the second argument being the set of assumptions. This means that a Lisp function could store information in an external datastructure, indexed under the appropriate assumptions, using rules something like the following:

        ((R ?x ?y)  ->  (:funcall #'Fout '?x '?y :assumptions))
        ((R ?x ?y)  <-  (:bind ?y (:funcall #'Fin '?x :assumptions)))

(This has not been tested, and the returned values will be cached in the slot, which may not be what we want.)

(:branch  variable expression)
(:branch (variable tex2html_wrap_inline1330 ) expression)

:branch works just like :bind, except that the result of evaluating expression must be a list of values, and variable is unified against each of those values along a separate branch.

Since parts of these forms are evaluated by Lisp after Algernon variables are replaced by their values, and since Algernon frames are represented by Lisp symbols that are often unbound, it is important to quote variables whose bindings shouldn't be evaluated. For example, if foo is a function taking a single numerical argument, then

((:bind ?f 'foo) (:bind ?n (:funcall '?f 2))) or even
((:bind ?f 'foo) (:bind ?n (?f 2))) will work as expected, but
((:bind ?f 'foo) (:bind ?n (:funcall ?f 2))) will not.


next up previous contents index
Next: Controlled Retrieval Up: Special Forms Previous: Calling Algernon from Lisp

Micheal S. Hewett
Tue Oct 29 11:28:38 CST 1996