Defining objects for easy reuse is a very important property for reducing the cost of large projects. One important technique is to define prototypes in a parameterized way, so that various instantiations of a prototype correspond to different uses. Parameterized or generic objects have been used for this purpose in other object-oriented systems. An object-identifier can be a compound term. The arguments of the term are parameters that are visible in the object-body. Here we show one example. Other examples and techniques that use this facility has been investigated extensively in [McCabe 92].
The following is an object sort
that sorts lists of different
types. sort
has a parameter that defines the type of the
elements of the list. Notice that Type is visible to all methods
in the body of sort
, and is used in the method
partition/4
. In the query, we use sort(rat)
to sort a
list of terms denoting rational numbers. We must therefore define a
rat
object and its <
method also:
rat :: { (P/Q < R/S) :- :(P*S < Q*R) }. sort(Type) :: { :- :use_module(library(lists), [append/3]) & qsort([], []) & qsort([P|L], S) :- partition(L, P, Small, Large), qsort(Small, S0), qsort(Large, S1), :append(S0, [P|S1], S) & partition([], _P, [], []) & partition([X|L1], P, Small, Large) :- ( Type :: (X < P) -> Small = [X|Small1], Large = Large1 ; Small = Small1, Large = [X|Large1] ), partition(L1, P, Small1, Large1) }. | ?- sort(rat) :: qsort([23/3, 34/11, 45/17], L). L = [45/17,34/11,23/3]
Parameterized objects are interesting in their own right in Prolog even if one is not interested in the object-oriented paradigm. They provide global context variables in a Prolog program without having to add such variables as additional context arguments to each clause that potentially uses the context.