# What is the best practice for "namespacing" imports?

**URL:** <https://swi-prolog.discourse.group/t/what-is-the-best-practice-for-namespacing-imports/3273>\
**Category:** Help!\
**Tags:** discussion\
**Created:** [November 18, 2020, 6:45pm UTC](https://swi-prolog.discourse.group/t/what-is-the-best-practice-for-namespacing-imports/3273 "2020-11-18T18:45:03Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![jchasinga](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jchasinga/32/3102_2.png) [@jchasinga](https://swi-prolog.discourse.group/u/jchasinga)\
**Post date:** [November 18, 2020, 6:45pm UTC](https://swi-prolog.discourse.group/t/what-is-the-best-practice-for-namespacing-imports/3273/1 "2020-11-18T18:45:03Z")

</div>

I’ve just learned that Prolog does not have the notion of namespaces. This potentially makes importing predicates from modules confusing. Is there a best practice among Prolog programmers for namespacing imports? Two hacks come to mind:

**Prepending every predicate with its parent module’s name**  
For example, `math_add/2` for an `add/2` in `math` module. This can get cumbersome fast not just because the long names but when maintenance is needed such as module refactor / name changing.

**Keep each module small**  
This seems like a more sustainable path. If an importing module is small as well as the exporting ones, the need to namespace becomes less important.

I’m a Prolog noob who have just fallen in love with the language, but yet to build a real world app. I have experience in a few “neighbor” languages like Erlang, Ocaml, and Lisp, so I was expecting Prolog to have had a similar namespace system as Erlang (`module:predicate/arity_num`) since the latter was heavily inspired by the first.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [November 18, 2020, 6:54pm UTC](https://swi-prolog.discourse.group/t/what-is-the-best-practice-for-namespacing-imports/3273/2 "2020-11-18T18:54:18Z")

</div>

I’m confused.

You are correct that Prolog does not have a namespace, i.e. `namespace_a.namespace_b.namespace_c.predicate`, but then you imply it does **not** have a module system like `module:predicate/arity_num` as you note in Erlang. But Prolog does have a module system like `module:predicate/arity_num`, see: [Defining a Module](https://www.swi-prolog.org/pldoc/man?section=defmodule). (as I don’t use Erlang I don’t know if `module:predicate/arity_num` is different from Prolog).

HTH

---

<div class="post-metadata">

**Author:** ![jchasinga](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jchasinga/32/3102_2.png) [@jchasinga](https://swi-prolog.discourse.group/u/jchasinga)\
**Post date:** [November 18, 2020, 7:26pm UTC](https://swi-prolog.discourse.group/t/what-is-the-best-practice-for-namespacing-imports/3273/3 "2020-11-18T19:26:51Z")

</div>

Hi @EricGT, thanks for chiming in. I meant that when importing predicates from a parent module, what is the best practice for working around the lack of namespaces?

```prolog
:- use_modules(foo).

% I can't do this
% foo:add(R, 1, 2).
% foo:minus(R, 10, 2).

% So This is my first resort
foo_add(R, 1, 2).
foo_minus(R, 10, 2).

I was wondering if there is a best practice most seasoned Prolog programmers use in this scenario.
```

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [November 18, 2020, 7:33pm UTC](https://swi-prolog.discourse.group/t/what-is-the-best-practice-for-namespacing-imports/3273/4 "2020-11-18T19:33:41Z")

</div>

I don’t do anything special, but I tend to list out all the imported predicates rather than import everything. (If you’ve done Python programming, it’s like the difference between `from foo import bar, zot` vs `from foo import *`. You can sort-of simulate `import foo; foo.bar()` but it doesn’t really fit with the module philosophy). Note that Prolog allows importing with another name, so if there’s a name clash, it’s easily taken care of.  
I also turn off [automatic loading](https://www.swi-prolog.org/pldoc/man?section=autoload), but there are many who disagree with me – my attitude is that I prefer maximum understanding from the code using as few tools as possible. Having said that, there are good cross-referencing tools, so if you don’t know where a predicate is defined, it’s easy to click on it and find out.

---

<div class="post-metadata">

**Author:** ![jchasinga](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jchasinga/32/3102_2.png) [@jchasinga](https://swi-prolog.discourse.group/u/jchasinga)\
**Post date:** [November 18, 2020, 7:36pm UTC](https://swi-prolog.discourse.group/t/what-is-the-best-practice-for-namespacing-imports/3273/5 "2020-11-18T19:36:05Z")

</div>

I did not know that we could alias an import, so this is great! Thanks for your answer.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [November 18, 2020, 7:46pm UTC](https://swi-prolog.discourse.group/t/what-is-the-best-practice-for-namespacing-imports/3273/6 "2020-11-18T19:46:56Z")

</div>

So here is a very simple example. Seems you might have figured this out based on the answer by Peter. This is also here for others looking to learn modules.

Directory: `C:/Users/Groot`

File: `foo.pl`

```prolog
:- module(foo,
    [
        add/3,
        minus/3
    ]).

add(R,A,B) :-
    R is A + B.

minus(R,A,B) :-
    R is A - B.

```

File: `bar.pl`

```prolog
:- module(bar,
    [
        test_01/0,
        test_02/0
    ]).

:- use_module(foo).

test_01 :-
    add(R,1,2),
    format('Result: ~w~n',[R]).

test_02 :-
    minus(R,2,1),
    format('Result: ~w~n',[R]).

```

Example run:

```prolog
?- working_directory(_,'C:/Users/Groot').
true.

?- [foo].
true.

?- [bar].
true.

?- test_01.
Result: 3
true.

?- test_02.
Result: 1
true.

```

HTH

* * *

Note: This is not the best way to do tests but it is more understandable for a beginner. See: [Prolog Unit Tests](https://www.swi-prolog.org/pldoc/doc_for?object=section(%27packages/plunit.html%27))

---

<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:** [November 19, 2020, 9:19am UTC](https://swi-prolog.discourse.group/t/what-is-the-best-practice-for-namespacing-imports/3273/7 "2020-11-19T09:19:51Z")

</div>

> [@jchasinga](#):
>
> so I was expecting Prolog to have had a similar namespace system as Erlang ( `module:predicate/arity_num` ) since the latter was heavily inspired by the first.

The time line gets difficult. SWI-Prolog (and a few others, such as YAP, Ciao and SICStus) got there module system from Quintus. Wikipedia says Erlang was started in 1986, which is pretty close to when Quintus got modules. So yes, in these module systems a fully qualified predicate indicator is module:name/arity and calls take the form module:name(arg1, arg2, …).

Each module is headed by a `:- module(Name, Exports).`, splitting its predicates in _exported_ and _private_ predicates. use\_module/1 imports all exported predicates from the target and use\_module/2 only the listed ones.

Using module:name(arg1, …) in your code is not what the developers had in mind. You can conclude that from two observations:

- The module:name(arg1, …) construct can call both exported and private predicates. The breaks the most important aspect of modules: distinguish the interface (exported preds) from the private ones, so you can do whatever you want to the implementation as long as you stick to the interface without harming the overall application.
- The module:name(arg1, …) changes the _module context_ to _module_, i.e., it acts as if the goal is called from inside _module_. This makes a difference if name(…) is a _meta predicate_, a predicate calling a goals passed in one or more of the arguments. Think of findall/3, maplist/3, etc. If we call `apply:maplist(mypred, List1, List2)` it will call `apply:mypred/2` rather than `mypred/2` in the module from which I make this call.

In other words, _qualified goals_ (module:name(arg1, …)) are intended for debugging and testing, not for production code.

So, how must we deal with this? One way as you suggest is to have fairly small modules (or more precisely, modules with a small interface). This reduces the probability of conflicts when using use\_module/1. Another is @peter.ludemann’s suggestion to use use\_module/2, possibly with the “… as myname” in case of a conflict (added to SWI-Prolog after discussion with Vitor Santos Costa from YAP).

The third option is the common practice in most of the libraries developed in the Quintus descendant systems. This uses a short prefix for the interface, so you get e.g. ord\_disjoint/2, ord\_subset/2, etc. Using this type of naming the risk for conflicts when using use\_module/2 or even relying on autoloading is pretty small. Note that relying on autoloading gets you pretty much in the same space as C, where you have static (private) functions and common functions that all live in the same namespace (in C the default is common, in Prolog private). The C way to live with that is similar, which is why all SWI-Prolog foreign symbols are called `PL_*`, X11 calls everything `X*`, etc.

Is this bad? I don’t know. The module names live in a flat namespace. This requires using module names that are rather long, typically including some _package prefix_, e.g., `http_dispatch`, `http_server`, etc. Shorter names can only be used for old common libraries such as `lists`. I’ve seen too many packages having a `utils` module. You can’t load two of these packages into the same Prolog instance. Well, actually you can as you can use load\_files/2 using the module(Name) option to load a module into a different module than the one mentioned in the header. If your code uses `utils:...` it still breaks ☹

A more modern solution would be to only allow module:name(…) calls to exported predicates and not switch the calling context. This probably should be combined with a `:- use_module(Path) as Name`, such that we can use Name:… to refer to this module regardless of the module name in Path. Logtalk has solved this stuff in a more modern way. Possibly the biggest added value is that it is what most people coming from other recent languages expect.

Migrating to that would require renaming all library modules and their predicates to reach at a coherent system. Is `ord_subtract(All, Subtract, Remain)` better than `ordsets:subtract(All, Subtract, Remain)`? It gets value if we have different implementations for the same interface. That is hard to do elegantly using this module system.
