packages proposal

Fergus Henderson fjh at cs.mu.OZ.AU
Tue Feb 10 22:09:01 AEDT 1998


Hi,

The tests failed last night because `extras/cfloat/cfloat_lib.m',
which is now compiled with `--halt-at-warn', got an error about
nothing exported in the interface section.  The reason it exports
nothing is that it is a package (i.e. a library of modules),
not a module.

The quick fix is to add a dummy type or pred to the interface.
But that's an ugly hack.

So, to solve this problem, I have a proposal for a new syntax for packages.

Syntax:

	:- package <ThisPackageName>.
	:- interface.
	:- import_package <PackageName>, <PackageName>, ...
	:- include_module <ModuleName>, <ModuleName>, ...

	:- implementation.
	:- import_package <PackageName>, <PackageName>, ...
	:- include_module <ModuleName>, <ModuleName>, ...
	:- end_package <ThisPackageName>.

Examples:

	Here's an arbitrary

		:- package foo.
		:- interface.
		:- import_package bar, baz.
		:- include_module m1, m2, m3.

		:- implementation.
		:- import_package quux.
		:- include_module m4, m5.
		:- end_package foo.

	Here's the package definition for the Mercury standard library.

		:- package std.
		:- interface.
		:- include_module io, string, char, ...

		:- implementation.
		:- import_package debugger_interface.

	Here's the package definition for the trailed_update package.

		:- package trailed_update.
		:- interface.
		:- import_package std.
		:- include_module tr_store, tr_array, var.

		:- implementation.
		:- include_module unsafe.

Semantics:

	The `:- package' and `:- end_package' declarations are
	analagous to `:- module' and `:- end_module' declarations, but
	for packages instead of modules.  `:- end_package' is optional.
	A package is like a module, but a package can contain only
	`include_module' declarations; packages may not declare or
	define any types, insts, modes, preds, funcs, typeclasses, or
	typeclass instances.

	An `:- import_package foo' declaration declares that this
	module or package makes use of modules defined in package
	`foo'.  Implementations could use this information to make
	it easier to use packages.  For example, for our current
	implementation, we could modify `mmc --generate-dependencies'
	to check for `import_package' declarations and would spit out
	appropropriate things in the `.dep' file which Mmake would use
	to include appropriate options when invoking `ml'. 

	The Mercury implementation could encourage the use of
	standard paths for a package based on the package name,
	just as the current implementation strongly encourages the use
	of the same module name and file name.
	Command-line options would specify the directory
	root, i.e. the first part of the path, for libraries
	(e.g. the default would be /usr/local/mercury-<version>/lib/mercury,
	but users could add additional ones), and the interface files
	and the .a and .so files would be searched for in standard locations
	relative to that root, e.g. $ROOT/ints/$PACKAGE/*.{int,int2,int3,opt},
	$ROOT/libs/lib$PACKAGE.a, $ROOT/libs/$PACKAGE.so, and
	$ROOT/modules/$PACKAGE.init.

	This would help us to make the "Using Libraries" section of the
	Mercury User's Guide a little less awful (currently you
	have to set about 5 different variables to import a library).

	Note that `import_package' declarations should be allowed in
	modules as well as in packages.  It would be good style for
	each package to have `import_package' declarations for any
	packages imported by modules which that package includes (in
	other words, the import_package declarations in a package
	should be the union of the import_package declarations in its
	modules); perhaps the compiler should check this.

	Initially, we will not allow explicit package qualifiers.
	Later, perhaps, we can add support for package qualifiers and
	`use_package' declarations (by analogy with `use_module').

	Note the use of `include_module' rather than `import_module'.
	This is becaused `include_module' makes a module part of a
	package, whereas `import_module' would just be saying that the
	package uses that module.  `include_module' declarations would
	be allowed only in packages, not in modules.

	Initially, we would leave the name mangling alone.
	Later, we can add a `--in-package <package-name>' option,
	and have `mmake package.depend' cause the files in that
	package to be compiled with this option, and have
	the compiler include the package name in the mangled name.
	Or we could allow module declarations of the
	form `:- module std.io' (or `:- module std:io', if we're
	still using `:' as module- and package- qualifier).

Because this proposal does not allow modules to contain other modules,
and because packages can contain only other modules, not types or
insts, etc., this proposal avoids much of the complexity that would
be associated with having.

One thing that this proposal does not address is meta-packages
(packages of packages) and/or hierarchical partitioning of the
package namespace (allowing `.' in package names).

I think meta-packages would probably be a bad idea (too much
complexity for too little gain), but I think you can probably
get most of the same effect using a hierarchical partitioning
of the package namespace.

Comments?

-- 
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