Another typical way to use the module system is for defining classes
within an object oriented paradigm. The class structure and the
methods of a class can be defined in a module and the explicit
module-boundary overruling describes in section
can by used by the message passing code to invoke the behaviour. An
outline of this mechanism is given below.
% Define class point :- module(point, []). % class point, no exports % name type, default access % value variable(x, integer, 0, both). variable(y, integer, 0, both). % method name predicate name arguments behaviour(mirror, mirror, []). mirror(P) :- fetch(P, x, X), fetch(P, y, Y), store(P, y, X), store(P, x, Y).
The predicates fetch/3 and store/3 are predicates that change instance variables of instances. The figure below indicates how message passing can easily be implemented:
% invoke(+Instance, +Selector, ?ArgumentList) % send a message to an instance invoke(I, S, Args) :- class_of_instance(I, Class), Class:behaviour(S, P, ArgCheck), !, convert_arguments(ArgCheck, Args, ConvArgs), Goal =.. [P|ConvArgs], Class:Goal.
The construct `Module:Goal' explicitely calls Goal in
module Module. It is discussed in more detail in
section .