Two approaches to realize a module system are commonly used in Prolog and other languages. The first one is the name based module system. In these systems, each atom read is tagged (normally prefixed) with the module name, with the exception of those atoms that are defined public. In the second approach, each module actually implements its own predicate space.
A critical problem with using modules in Prolog is introduced by the meta-predicates that transform between Prolog data and Prolog predicates. Consider the case where we write:
:- module(extend, [add_extension/3]). add_extension(Extension, Plain, Extended) :- maplist(extend_atom(Extension), Plain, Extended). extend_atom(Extension, Plain, Extended) :- atom_concat(Plain, Extension, Extended).
In this case we would like maplist to call extend_atom/3 in the
module
extend
. A name based module system will do this correctly.
It will tag the atom extend_atom
with the module and
maplist will use this to construct the tagged term extend_atom/3. A name
based module however, will not only tag the atoms that will eventually
be used to refer to a predicate, but all atoms that are
not declared public. So, with a name based module system also data is
local to the module. This introduces another serious problem:
:- module(action, [action/3]). action(Object, sleep, Arg) :- .... action(Object, awake, Arg) :- .... :- module(process, [awake_process/2]). awake_process(Process, Arg) :- action(Process, awake, Arg).
This code uses a simple object-oriented implementation technique were atoms are used as method selectors. Using a name based module system, this code will not work, unless we declare the selectors public atoms in all modules that use them. Predicate based module systems do not require particular precautions for handling this case.
It appears we have to choose either to have local data, or to have trouble with meta-predicates. Probably it is best to choose for the predicate based approach as novice users will not often write generic meta-predicates that have to be used across multiple modules, but are likely to write programs that pass data around across modules. Experienced Prolog programmers should be able to deal with the complexities of meta-predicates in a predicate based module system.