View mode: basic / threaded / horizontal-split · Log in · Help
February 01, 2008
Modules
This comes after a short discussion on the #D IRC channel. The topic is complex, and I don't know all its complexities. Generally I try to talk only about the things I know, so here I don't talk about some things (like packages, etc. For the interested people this may be interesting: http://www.python.org/dev/peps/pep-0328/ ).

I think the current way D manages modules has some small problems, despite being usable enough anyway.

I think the purposes of a module system like the Python-like D currently has, are:
- to manage name spaces
- to avoid name clashes and to avoid using the names coming from the wrong name spaces.

So the most important qualities it must have are:
- It imports as few names as possible from one namespace to another one. Having less names around as possible is generally very good;
- it must be very clear to the programmer what names are imported, and where each one of them comes from;
- Another quality is the ability to import all names from a name space (a module), this can be useful in particular circumstances (like quick-and-dirty script-like programs) to reduce programming time of small scripts, but such ability can't be the default one.
- We have to remember that a module name is a name, like any other function/variable name.

So I think something like this:

module foo;
import somemodule1;
import package.somemodule2;

has to import only two names in the current namespace:

somemodule1
package.somemodule2

So if you want to use what's inside them you have to use:

somemodule1.name1
package.somemodule2.name2

If a third module imports foo, like this:

import foo;

It imports just the "foo" name, and it doesn't contain somemodule1 and package.somemodule2 names.

"public import" can be used to allow the presence of the "somemodule1" and "package.somemodule2" names inside the module that has imported "foo". But D conventions have to discourage this practice.

A command like:

import somemodule1: name1;

Has to import just 1 name in the current namespace, "name1", not "somemodule1" name too.

Both Python and Java have a way to import all names from another namespace/module:

from somemodule1 import *
import name1.*;

So D can add one of such ways, like:

import name1.*;
or the commonly used:
import name1.all;
Or something else still.

That command imports in the current namespaces all the names contained in the "name1" namespace, but not the "name1" name itself. D conventions have to discourage this practice in programs more than 30 lines long, but in particular situations it's useful.


I think the DMD compiler has to be able to recursively find by itself the modules, like the "bud" tool does, because duplicating the information is generally bad in computer science. In the situations where this behavior isn't appreciated (for example large projects, etc) it can be added a flag to DMD to disable the automatic file retrieval ("bud" has the -explicit and -names flags to manage such things, and I think they work well enough).

D 1.x can't be changed now, but 2.x is new so such import semantics can be discussed and improved. Fixing such problems later may become more difficult.

Bye,
bearophile
Top | Discussion index | About this forum | D home