next up previous

8.4.3 Method Parameter Restrictions

Each parameter for a method can be defined to have arbitrarily complex restrictions or none at all. A parameter restriction is applied to a generic function argument at runtime to determine if a particular method will accept the argument. A parameter can have two types of restrictions: type and query. A type restriction constrains the classes of arguments that will be accepted for a parameter. A query restriction is a user-defined boolean test which must be satisfied for an argument to be acceptable. The complexity of parameter restrictions directly affects the speed of the generic dispatch.

A parameter that has no restrictions means that the method will accept any argument in that position. However, each method of a generic function must have parameter restrictions that make it distinguishable from all of the other methods so that the generic dispatch can tell which one to call at runtime. If there are no applicable methods for a particular generic function call, CLIPS will generate an error (see section 8.5.4 for more detail).

A type restriction allows the user to specify a list of types (or classes), one of which must match (or be a superclass of) the class of the generic function argument. If COOL is not installed in the current CLIPS configuration, the only types (or classes) available are: OBJECT, PRIMITIVE, LEXEME, SYMBOL, STRING, NUMBER, INTEGER, FLOAT, MULTIFIELD, FACTADDRESS and EXTERNALADDRESS. Section 9 describes each of these system classes. With COOL, INSTANCE, INSTANCEADDRESS, INSTANCENAME, USER, INITIALOBJECT and any userdefined classes are also available. Generic functions which use only the first group of types in their methods will work the same whether COOL is installed or not. The classes in a type restriction must be defined already, since they are used to predetermine the between a generic function's methods (see section 8.5.2 for more detail). Redundant classes are not allowed in restriction class lists. For example, the following method parameter's type restriction is redundant since INTEGER is a subclass of NUMBER.

Example

(defmethod foo ((?a INTEGER NUMBER)))

If the type restriction (if any) is satisfied for an argument, then a query restriction (if any) will be applied. The query restriction must either be a global variable or a function call. CLIPS evaluates this expression, and if it evaluates to anything but the symbol FALSE, the restriction is considered satisfied. Since a query restriction is not always satisfied, queries should not have any sideeffects, for they will be evaluated for a method that may not end up being applicable to the generic function call. Since parameter restrictions are examined from left to right, queries which involve multiple parameters should be included with the rightmost parameter. This insures that all parameter type restrictions have already been satisfied. For example, the following method delays evaluation of the query restriction until the classes of both arguments have been verified.

Example

(defmethod foo ((?a INTEGER) (?b INTEGER (> ?a ?b))))

If the argument passes all these tests, it is deemed acceptable to a method. If all generic function arguments are accepted by a method's restrictions, the method itself is deemed applicable to the set of arguments. When more than one method is applicable to a set of arguments, the generic dispatch must determine an ordering among them and execute the first one in that ordering. Method precedence is used for this purpose and will be discussed in section 8.5.2.

Example

In the following example, the first call to the generic function "+" executes the system operator "+", an implicit method for numerical addition. The second call executes the explicit method for string concatenation, since there are two arguments and they are both strings. The third call generates an error because the explicit method for string concatenation only accepts two arguments and the implicit method for numerical addition does not accept strings at all.

CLIPS> (clear)
CLIPS>
(defmethod + ((?a STRING) (?b STRING))
    (str-cat ?a ?b))
CLIPS> (+ 1 2)
3
CLIPS> (+ "foo" "bar")
"foobar"
CLIPS> (+ "foo" "bar" "woz")
[GENRCEXE1] No applicable methods for +.
FALSE


next up previous