for review: add nested modules [5/5]

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Mar 4 20:00:17 AEDT 1998


On 04-Mar-1998, Peter Schachte <pets at students.cs.mu.OZ.AU> wrote:
> > > I don't think you mean fully-qualified.  Will you have to write
> > > 
> > > 	:- import_module :std:list.
> > > 
> > > to import the list module?
> > 
> > If/when we add support for a leading ":" in module names,
> > then we should revisit the use of the term "fully-qualified" here.
> 
> Alright, will you have to write
> 
>      :- import_module std:list.
> 
> to import the list module?  That's what you're saying.

Yes.

> It's also
> inconsistent:  you don't have to fully qualify anthing else in a module you
> import.

Yes, you're right, it is inconsistent.

The reason for the inconsistency is to make implementation easier.

This inconsistent requirement for using the fully-qualified
module name in `:- import_module' declarations may eventually go away,
so maybe we should move it to the "implementation bugs and limitations"
section.  However, I wasn't sure how difficult it would be to implement,
so I decided to be conservative for the moment, and to describe the
use of unqualified module names in import_module declarations as
a feature that is missing from the language rather than one that
is missing from the implementation.  We can revisit this if it
turns out to be easy to implement.

> > > > +The mapping between module names and source file names is
> > > > +implementation-defined.  (The University of Melbourne Mercury
> > > > +implementation requires a module named @samp{foo:bar:baz} to be
> > > > +located in source file @file{foo.bar.baz.m}.)
> > > 
> > > This is going to bite you someday, whether due to filename length
> > > limits on some unices, or braindead DOS 8.3 restrictions, or limits on
> > > the number of `.' characters in a file name. 
> > 
> > Implementations on OSs which don't support such file names
> > can use different file naming conventions, or can (for example)
> > allow the user to provide a file containing the mapping between
> > module names and source files.
> 
> And at that time you can consider yourself bitten.  Actually it's not so
> much you that will be bitten as the poor saps who have to contend with
> porting Mercury code to such a machine.  This bug bite (well, misfeature
> bite) could be avoided if users fully qualify separate submodule names. 

It would be easy enough to provide a tool to automatically rename
files to fit braindead filename restrictions and to automatically
produce the file containing the file name to module name mapping.
(In fact, such a tool already exists: the freely available `mkisofs'
program includes support for this.)

So, if/when it does bite, the fix will be simple enough.

> > > And, as I argued before,
> > > a switch in the Mmakefile isn't the right place for this information,
> > > either.
> > 
> > if the user can't easily
> > figure out a module's fully-qualified name when reading it, then
> > he can't tell which parent modules it implicitly imports.
> > But that's a separate issue.
> 
> That's the issue I'm raising.

I don't see exactly what this issue has to do with the file naming convention.

> > > So a module must both include and use a separate submodule in order to
> > > have access to its contents?
> > 
> > Yep.
> 
> Why?  This seems rather a nuissance, since there's not much point in having
> a submodule you can't use. 

Sure there is.  For example, the top-level module `std' will not have
any `use_module' or `import_module' declarations; it just *contains*
its sub-modules, In this example (and I expect it to be a common case,
perhaps the most common), the `use_module' or `import_module'
declarations to allow one child to make use of another will be inside
the sub-modules.

> So does this mean then that a module can have contents that it exports but
> doesn't itself have access to?

Not quite.  (The reason here is again the distinction between a sub-module
and the sub-module's contents.)

First, it is helpful to distinguish between accessibility and visibility.
An entity in the interface section of a module is accessible to all modules.
An entity in the implementation section of a module is accessible only to
that that module and its descendents. 
However, accessible entities are not necessarily visible.
Entities defined in a given module or in its ancestors are automatically
visible in that module.  Accessible entities defined in other modules
are visible only if the module they are defined in is explicitly imported
using `:- import_module' or `:- use_module'.
(Inaccessible entities are never visible.)

A module has access to its own contents, including
all entities (such as sub-modules) that it exports,
and of course such entities are automatically visible
in that module without the module needing to explicitly import itself ;-).
However, the *contents* of those entities are not automatically visible.

> That's a new feature.

Well, being able to define entities which can themselves have contents
is a new feature, yes.

> Until now a module always had access to all the "contents" of everthing
> inside itself.

That was true only in a vacuous sense -- previously nothing inside
a module had contents.

Well, I guess you could say that a type "contains" its constructors,
or that a typeclass "contains" its methods.  But that's a bit different.
Types and typeclasses don't provide any encapsulation of their
sub-entities.  The constructors in a type or the methods in a
typeclass are considered to be direct members of the containing module,
not members of the type or typeclass.

> Submodules should have you a way to hide private things, but
> I don't see why they should even hide public things from their parent
> (especially since the parent so generously shares all its contents with
> them).

If entities defined in the child modules were automatically visible in the
parent, then either
	- entities defined in the child modules must also be automatically
	  be visible in their sibling modules
or
	- there are some entities which are visible in the parent which
	  are not visible in the children.

Both of these alternatives seem to be undesirable.
That, plus the observation that in the common case the parent module
would itself use only a small subset of the modules it contains,
was why I dropped the implicit "use" of child modules in their ancestors.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list