# Module loading

**URL:** <https://swi-prolog.discourse.group/t/module-loading/2008>\
**Category:** Help!\
**Tags:** bug, discussion\
**Created:** [March 12, 2020, 9:48pm UTC](https://swi-prolog.discourse.group/t/module-loading/2008 "2020-03-12T21:48:50Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![dtonhofer](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dtonhofer/32/902_2.png) [@dtonhofer](https://swi-prolog.discourse.group/u/dtonhofer)\
**Post date:** [March 12, 2020, 9:48pm UTC](https://swi-prolog.discourse.group/t/module-loading/2008/1 "2020-03-12T21:48:50Z")

</div>

Here is something unexpected about Modules:

Suppose you have two modules:

In `file1.pl`:

```prolog
:-module('com.example.megacorp', [make_money/2]).

make_money("Make more money!", "Yes, sir").

```

In `file2.pl`:

```prolog
:-module('com.example.megacorp.hq', [make_money/2]).

make_money("Make more money!", "Yes, sir").

```

Note that the module names differ, but the exported _predicates_ have the same _descriptor_ (using correct [ISO terminology](https://stackoverflow.com/questions/49898738/is-this-prolog-terminology-correct-fact-rule-procedure-predicate), the exported _procedures_ have the same _predicate indicator_, but we know what we mean)

Then, in the REPL:

```prolog
?- [file1].
true.

?- [file2].
ERROR: import/1: No permission to import 'com.example.megacorp.hq':make_money/2 into user (already imported from 'com.example.megacorp')
true.

```

Okay. But now:

In `file1.pl`, unchanged:

```prolog
:-module('com.example.megacorp', [make_money/2]).

make_money("Make more money!", "Yes, sir").

```

In `file2.pl`, I leave the list of publicly visible predicates as it was (erroneously) and just change the name of the defined procedure:

```prolog
:-module('com.example.megacorp.hq', [make_money/2]).

make_money_2("Make more money!", "Yes, sir").

```

Unexpectedly, both files can be loaded.

```prolog
?- [file1].
true.

?- [file2].
true.

```

I didn’t expect that. Why is this possible?

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [March 12, 2020, 11:02pm UTC](https://swi-prolog.discourse.group/t/module-loading/2008/3 "2020-03-12T23:02:26Z")

</div>

Try (with the second version of your modules):

```nohighlight
?- [file1].
true.

?- [file2].
true.

?- predicate_property('com.example.megacorp.hq':make_money(_, _), imported_from(M)).
M = 'com.example.megacorp'.

```

Art this point, you would possibly reply that the second module doesn’t import the first module. True. But when loading the first module, it exports the `make_money/2` predicate to module `user` (which is the file loading context). As (SWI-Prolog) modules inherited predicates by default from `user`, you get no errors when loading the second file and you can use queries such as:

```nohighlight
?- 'com.example.megacorp.hq':make_money(A, B).
A = "Make more money!",
B = "Yes, sir".

```

And now, exhibiting great restraint, I will end my explanation with no judgement passed on Prolog modules.

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [March 13, 2020, 5:24am UTC](https://swi-prolog.discourse.group/t/module-loading/2008/4 "2020-03-13T05:24:34Z")

</div>

Disclaimer: From what I know about modules, I have concluded that we cannot use modules _as they are at the moment_ for object-oriented programming with polymorphism.

There is something I need to ask first. Why make modules and then use

```
?- [filename].

```

instead of

```
?- use_module(module_name).

```

… and why the `com.something.somethingelse.omg` module names?

Here is what I get with three modules:

```prolog
$ cat m1.pl
:- module(m1, [foo/1]).

foo('This is in module m1').
$ cat m2.pl
:- module(m2, [foo/1]).

foo('This is in the m2 module').
$ cat m3.pl
:- module(m3, [foo/1]).

bar('I made a mistake').

```

* * *

```prolog
?- use_module(m1).
true.

?- use_module(m2).
ERROR: import/1: No permission to import m2:foo/1 into user (already imported from m1)
true.

?- foo(X).
X = 'This is in module m1'.

?- m2:foo(X).
X = 'This is in the m2 module'.

```

This so far makes sense, intuitively, and doesn’t feel misleading.

The issue that @pmoura showed is indeed bad. Here it is, a bit more obvious to my eyes at least.

First, still OK – load a module that has a programmer’s mistake in it:

```prolog
$ swipl -q
?- use_module(m3).
ERROR: Exported procedure m3:foo/1 is not defined
true.

```

Now, quite bad – load first a module that is fine, than the module that has a mistake in it:

```prolog
$ swipl -q
?- use_module(m1).
true.

?- use_module(m3).
true. % Hmm....

?- foo(X).
X = 'This is in module m1'.

?- m3:foo(X).
X = 'This is in module m1'. % Oh noes

```

---

<div class="post-metadata">

**Author:** ![dtonhofer](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dtonhofer/32/902_2.png) [@dtonhofer](https://swi-prolog.discourse.group/u/dtonhofer)\
**Post date:** [March 13, 2020, 7:39am UTC](https://swi-prolog.discourse.group/t/module-loading/2008/5 "2020-03-13T07:39:23Z")

</div>

> [@Boris](#):
>
> There is something I need to ask first. Why make modules and then use
> 
> ```prolog
> ?- [filename].
> 
> ```
> 
> instead of
> 
> ```prolog
> ?- use_module(module_name).
> 
> ```
> 
> … and why the `com.something.somethingelse.omg` module names?

1. Hmm … not sure. I just wanted to get the modules into the runtime. Is there is a difference? There better not be.
2. The [SWI Prolog manual](https://eu.swi-prolog.org/pldoc/man?section=defmodule) says _Modules are organised in a single and flat namespace and therefore module names must be chosen with some care to avoid conflicts._ This problem exists also in Java, and Java’s convention for avoiding package name clashes – using the reverse domain name of the issuing organization, suitably suffixed --, immediately presents itself as solution. I just retained this in this example.

(About which, for people not _au fait_ with the Java ecosystem: There is the [Java package conventions](https://en.wikipedia.org/wiki/Java_package) from the 90s, the [OSGi Module system](https://en.wikipedia.org/wiki/OSGi), a complete module management system and there is the [Java (Platform) Module system](https://en.wikipedia.org/wiki/Java_Platform_Module_System), used mostly for modularizing the JDK.)

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [March 13, 2020, 7:50am UTC](https://swi-prolog.discourse.group/t/module-loading/2008/6 "2020-03-13T07:50:33Z")

</div>

> [@dtonhofer](#):
>
> Is there is a difference? There better not be.

I don’t know for sure. I guess we’d have to RTFM to figure it out :-). I always assumed there must be a difference, since you write the two things differently. Why have two different things if they are identical?

I might be wrong about this, but the underlying issue that Java package naming solved stems from not distributing source code? Or maybe it has something to do with “everything must be a class in its own class file” straight-jacket?

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [March 13, 2020, 8:06am UTC](https://swi-prolog.discourse.group/t/module-loading/2008/7 "2020-03-13T08:06:37Z")

</div>

> [@Boris](#):
>
> Disclaimer: From what I know about modules, I have concluded that we cannot use modules _as they are at the moment_ for object-oriented programming with polymorphism.

Modules **are** objects (see e.g. [Modules are objects - Logtalk](https://logtalk.org/2019/09/19/modules-are-objects.html)). Just poorly designed **as** an object system (which was never the intent). See e.g. [Blog - Logtalk](https://logtalk.org/blog.html?tag=half+broken+hacks) for some of the main problems in using modules systems as full fledge objects systems.

> [@Boris](#):
>
> The issue that @pmoura showed is indeed bad.

Indeed you can get a compilation error or a successful loading depending just on the file loading order (of two \*\*independent \*\* modules).

---

<div class="post-metadata">

**Author:** ![dtonhofer](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dtonhofer/32/902_2.png) [@dtonhofer](https://swi-prolog.discourse.group/u/dtonhofer)\
**Post date:** [March 13, 2020, 8:08am UTC](https://swi-prolog.discourse.group/t/module-loading/2008/8 "2020-03-13T08:08:03Z")

</div>

> I don’t know for sure. I guess we’d have to RTFM to figure it out :-). I always assumed there must be a difference, since you write the two things differently. Why have two different things if they are identical?

Well, generally it is desire for backward compatibility. One wants to change the functionality in a rational way, or even dump some of it, but that’s not possible because of that one company that lost its source code in the great harddisk crash of '77 and people like the old way or it’s faster to type. At best, you then have different ways of doing, at worst your system is getting increasingly paraconsistent (“don’t call X before Y or all hell breaks loose”).

> I might be wrong about this, but the underlying issue that Java package naming solved stems from not distributing source code?

No, it was just about how to name packages so that no two origins exist for a package named for example “logging”. The great thing is that you don’t need the source to discover the API (but the JavaDoc is really useful), but if a package name clash occurs, there is trouble (that can be solved by creating a separate [Classloader](https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html) instance as I remember, but this is ugly).

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [March 13, 2020, 8:11am UTC](https://swi-prolog.discourse.group/t/module-loading/2008/9 "2020-03-13T08:11:50Z")

</div>

> [@pmoura](#):
>
> As (SWI-Prolog) modules inherited predicates by default from `user`

Correct

> [@pmoura](#):
>
> no judgement

The user module plays a special role for mostly historical reasons, but also to facilitate unstructured programming, which has its advantages for code that is more or less intended for single use. If you do not want this, use a module for every part of your code and do not use `user`, with a possible exception of making the entry point of your program. I hardly ever write non-module code, except for very quick tests or single use programs.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [March 13, 2020, 8:17am UTC](https://swi-prolog.discourse.group/t/module-loading/2008/10 "2020-03-13T08:17:33Z")

</div>

> [@dtonhofer](#):
>
> Hmm … not sure. I just wanted to get the modules into the runtime. Is there is a difference? There better not be.

The only difference between [file] and use\_module(file) is that the latter raises an error if the file is not a module. I’d always use use\_module in code, but at the toplevel [file] is quicker to type.

Sorry, use\_module only loads the file if it is not loaded. [file] \_reloads\_the file if it is loaded. Tyoically not needed in SWI as there is make/0.

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [March 13, 2020, 8:20am UTC](https://swi-prolog.discourse.group/t/module-loading/2008/11 "2020-03-13T08:20:43Z")

</div>

> [@jan](#):
>
> The user module plays a special role for mostly historical reasons, but also to facilitate unstructured programming, which has its advantages for code that is more or less intended for single use. If you do not want this, use a module for every part of your code and do not use `user` […].

But the issue here is that `user` is used by **default**. People use modules to partitioning their code and often are oblivious that their code only works (instead of getting compilation errors) because of the default inheritance from the `user` module and some luck in compilation/loading order. This is not a theoretical problem and this issue is easy to find in the public Prolog codebases.

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [March 13, 2020, 8:22am UTC](https://swi-prolog.discourse.group/t/module-loading/2008/12 "2020-03-13T08:22:59Z")

</div>

> [@jan](#):
>
> use a module for every part of your code and do not use `user` , with a possible exception of making the entry point of your program.

OK, so just to check if I understand what you are saying. Instead of loading from the top level, I made another module that uses the two (conflicting) modules. It now looks much better. Here is the content of the three modules:

```prolog
$ cat m1.pl
:- module(m1, [foo/1]).

foo('This is in module m1').
$ cat m3.pl
:- module(m3, [foo/1]).

bar('I made a mistake').
$ cat top.pl
:- module(top, [m1_foo/1, m3_foo/1]).

:- use_module(m1).
:- use_module(m3).

m1_foo(X) :-
    foo(X).

m3_foo(X) :-
    m3:foo(X).

```

And here is what happens when I try to use the `top` module:

```prolog
?- use_module(top).
ERROR: /home/boris/code/own/prolog/modules/top.pl:4:
ERROR: Exported procedure m3:foo/1 is not defined
ERROR: /home/boris/code/own/prolog/modules/top.pl:4:
ERROR: import/1: No permission to import m3:foo/1 into top (already imported from m1)
true.

?- m1_foo(X).
X = 'This is in module m1'.

?- m3_foo(X).
ERROR: Unknown procedure: m3:foo/1
ERROR: In:
ERROR: [11] m3:foo(_22348)
ERROR: [10] top:m3_foo(_22378) at /home/boris/code/own/prolog/modules/top.pl:10
ERROR: [9] <user>
   Exception: (11) m3:foo(_15152) ? creep
?- m3:bar(X).
X = 'I made a mistake'.

```

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [March 13, 2020, 8:36am UTC](https://swi-prolog.discourse.group/t/module-loading/2008/13 "2020-03-13T08:36:40Z")

</div>

> [@Boris](#):
>
> OK, so just to check if I understand what you are saying. Instead of loading from the top level, I made another module that uses the two (conflicting) modules. It now looks much better.

Actually, your example also illustrates the danger of `use_module/1` directives. Consider the following variant of your modules:

```prolog
$ cat m1.pl
:- module(m1, [foo/1]).

foo('This is in module m1').
$ cat m2.pl
:- module(m2, [bar/1]).

bar('This is in module m2').
$ cat top.pl
:- module(top, [p/0]).

:- use_module(m1).
:- use_module(m2).

p :- foo(_), bar(_).

```

You load the `top` module. Everything is fine. Later module `m2` is update to:

```prolog
:- module(m2, [foo/1, bar/1]).

foo('I am new here!').
bar('This is in module m2').

```

Your application no longer compiles (generating the error that you illustrated) despite the fact then, when you wrote it, you intended to take `foo/1` from `m1`. Problem is, the `m1:foo/1` dependency is implicit. Same for the `m2:bar/1` dependency. This makes any dependency updates potentially hazardous. Not something that should keep people awake at night but definitely something that people should be aware.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [March 13, 2020, 9:32am UTC](https://swi-prolog.discourse.group/t/module-loading/2008/14 "2020-03-13T09:32:47Z")

</div>

> [@pmoura](#):
>
> Your application no longer compiles (generating the error that you illustrated) despite the fact then, when you wrote it, you intended to take `foo/1` from `m1` . Problem is, the `m1:foo/1` dependency is implicit.

True. Modules are not objects/classes though and where methods tend to be short and not carrying a clue on the data processed, predicates tend to carry a hint on the data or _family_ they belong to such as http\_open/3. There are of course the historical exceptions (yes, transpose/2 is one). Using these conventions it should be practically impossible to get into a conflict. If you do not want to use longer names you can use use\_module/2. Note that that may imply having to use `module:goal`, which IMO is a rather bad idea. For one thing, it makes tracking the dependencies a lot harder. Also, module names should be fairly long to avoid conflicts while an indication of where the predicate belongs to can be much shorter as conflicts only arise where different contexts are loaded into the same module and have similar operations.

I still mostly disagree the module system is badly broken. Only, you should use it as intended and one could probably claim tutorials on that are note spread widely enough.

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [March 13, 2020, 10:13am UTC](https://swi-prolog.discourse.group/t/module-loading/2008/15 "2020-03-13T10:13:57Z")

</div>

> [@jan](#):
>
> True. Modules are not objects/classes though

Modules **are** objects. They are not classes, however, but prototypes (OO doesn’t imply classes; anyone thinking that have a lot to learn about OO). Here:

> **[Modules are objects - Logtalk](https://logtalk.org/2019/09/19/modules-are-objects.html)**
>
> Prolog modules are objects. This statement may surprise you. From past experience, it will also annoy some Prolog practitioners. It is not the case that the ...

> [@jan](#):
>
> … and where methods tend to be short and not carrying a clue on the data processed, predicates tend to carry a hint on the data or _family_ they belong to such as http\_open/3. There are of course the historical exceptions (yes, transpose/2 is one). Using these conventions it should be practically impossible to get into a conflict.

Indeed following (naming) conventions goes a long way in avoiding conflicts. That, however, doesn’t imply that those conventions are a best practice by itself. E.g. reusing names simplify learning APIs and make them consistent.

> [@jan](#):
>
> If you do not want to use longer names you can use use\_module/2. Note that that may imply having to use `module:goal` , which IMO is a rather bad idea. For one thing, it makes tracking the dependencies a lot harder.

There is no reason for it to be harder other than current limitations on the (SWI-Prolog) tools or the (SWI-Prolog) reflection API support. E.g. Logtalk tools and reflection API have no issue tracking module dependencies independently of implicit or explicit qualification.

> [@jan](#):
>
> I still mostly disagree the module system is badly broken.

A classic case of Stockholm syndrome. After +20 years of sharing alternative and elegant solutions based on constructs actually designed to tackle software engineering issues and requirements, the most common reaction I get from Prolog implementers/vendors (not users, implementers/vendors) is silence or hostility or half-broken ugly hacks that attempt to the same within the module systems.
