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.