Creating more than one Modules in one File for dict methods

When I create methods (or in swl speech functions, but I like to call it methods because it looks like methods in OO languages) for dicts I am forced to create another file.

Discourse proposed another thread to me in which this topic was already discussed but it showed no obvious solution.

( Multiple modules definitions in one file? )

Suppose I would be able to create a new module B inside another module A that would mean that module B is in a way global like all modules in this module system. So in a bigger project I could loose the oversight and accidentially define the same module twice.

Maybe it is possible to introduce module namespaces like in C++ in this case that would mean the inner module is globally named A::B (maybe shorter in the module itself) and then I were able to introduce dict methods inplace without the need to create a new file and I would have a better code hiding.

This module extension would also be good for dynamic modules. Several modules could use inner modules dynamically (like objects) without the risc for a conflict.

You don’t really have to create a module using a file. You can simply write in any module


to get … into a (possibly new) module mymodule. That is enough to add a method to a dict AFAIK.

As you not though, modules live in a single global space. Surely the current module system, based on the Quintus’ module system designed in the late 80s has its limitations. It would be interesting to brainstorm on options to improve on that without too much implications for existing applications. Fixing the above probably require an “atom based” module system that comes with its own problems. XSB uses a “functor based” module system. That is an interesting thought.

I think when we want to stick to atoms for modules which makes sense, we could create a predicate create_sub_module(M), which creates an alias for the context_module followed by M as M . Another module named M would be shadowed then.

It could be interesting to use it with an on/off mechnism and to be able to use it inside a single rule.

We maybe need a predicate to make an alias for the shadowed module if we need it.

:- module( m, []).

% creates an alias named c for the shadowed module b
:- create_module_alias(b, c). 

% alias b is referring to module mb, module b is shadowed
% gives a warning if the shadowed module b has no alias
:- create_sub_module(b). 

% this would create an alias for module mb at this position
% :- create_module_alias(b, c). 

% the predicates drop_module_alias and drop_sub_module revert it again

% in a predicate:

% creates a dynamic submodule md and aliases it to d temporarily
p :- ..., create_sub_module(d), ... , drop_sub_module(d) ... .

It won’t fix the problem mapping dict tags to modules as the dict tag is a simple plain atom. Something similar holds for variable attributes that are mapped to modules for calling the various hooks. For that, it seems one needs to associate atoms with modules, creating an “atom based module system” as opposed to a “predicate based module system”.

Note that one can create “sub modules”, although the API is only partially public. PlUnit test units (:- begin_tests(....) ... :- end_tests(...)) create a module that inherits from the module in which it is created, which implies that it sees the predicates from the outer module and inherits operators from that module.

It is surely worth thinking about extending the module system, though preferably together with other systems that inherited the Quintus module system as this fairly large group of systems is still sufficiently compatible to write basic portable modules.