next up previous

8.4.4 Method Wildcard Parameter

A method may accept exactly or at least a specified number of arguments, depending on whether a wildcard parameter is used or not. The regular parameters specify the minimum number of arguments that must be passed to the method. Each of these parameters may be referenced like a normal single-field variable within the actions of the method. If a wildcard parameter is present, the method may be passed any number of arguments greater than or equal to the minimum. If no wildcard parameter is present, then the method must be passed exactly the number of arguments specified by the regular parameters. Method arguments which do not correspond to a regular parameter can be grouped into a multifield value that can be referenced by the wildcard parameter within the body of the method. The standard CLIPS multifield functions, such as length$ and expand$, can be applied to the wildcard parameter.

If multifield values are passed as extra arguments, they will all be merged into one multifield value referenced by the wildcard parameter. This is because CLIPS does not support nested multifield values.

Type and query restrictions can be applied to arguments grouped in the wildcard parameter similarly to regular parameters. Such restrictions apply to each individual field of the resulting multifield value (not the entire multifield). However, expressions involving the wildcard parameter variable may be used in the query. In addition, a special variable may be used in query restrictions on the wildcard parameter to refer to the individual arguments grouped into the wildcard: ?current-argument. This variable is only in scope within the query and has no meaning in the body of the method. For example, to create a version of the "+" operator which acts differently for sums of all even integers:

Example

CLIPS>
(defmethod +
  (($?any INTEGER (evenp ?current-argument)))
  (div (call-next-method) 2))
CLIPS> (+ 1 2)
3
CLIPS> (+ 4 6 4)
7
CLIPS>

It is important to emphasize that query and type restrictions on the wildcard parameter are applied to every argument grouped in the wildcard. Thus in the following example, the > and length$ functions are actually called three times, since there are three arguments:

Example

CLIPS> (defmethod foo (($?any (> (length$ ?any) 2))) yes)
CLIPS> (foo 1 red 3)
yes
CLIPS>

In addition, a query restriction will never be examined if there are no arguments in the wildcard parameter range. For example, the the previous methodwould be applicable to a call to the generic function with no arguments because the query restriction is never evaluated:

Example

CLIPS> (foo)
yes
CLIPS>

Typically query restrictions applied to the entire wildcard parameter are testing the cardinality (the number of arguments passed to the method). In cases like this where the type is irrelevant to the test, the query restriction can be attached to a regular parameter instead to improve performance (see section 8.5.1). Thus the previous method could be improved as follows:

Example

CLIPS> (clear)
CLIPS> (defmethod foo ((?arg (> (length$ ?any) 1)) $?any) yes)
CLIPS> (foo)
[GENRCEXE1] No applicable methods for foo.
FALSE
CLIPS>

This approach should not be used if the types of the arguments grouped by the wildcard must be verified prior to safely evaluating the query restriction.


next up previous