[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

OOC Package Tool (2)



The first mail did not trigger any hot responses.  This encourages me
to push the topic a little bit further.  In particular I want to fix
some details of the three topics that were somewhat mixed together in
my first mail:
  
  a) hierarchical module namespace
  b) distribution packages
  c) package versioning



Hierarchical Module Namespace
-----------------------------

Some time ago I wrote:
> To pass package information to the compiler, I propose a minimalistic
> change to the Oberon-2 IMPORT statement.  In addition to the import
> clause
> 
>   ident [":=" ident]
> 
> there is a second variant, 
> 
>   ident := ident {"." ident}
> 
> to access a module from a package.

I was lying.  Actually I want a second change to O2: the module should
have its own fully qualified name in its header.  A module `Files'
from the core library would declare itself as

  MODULE Core.Files;
    ...
  END Core.Files.

This change enforces consistent naming and makes it much simpler to
create a global namespace (on the linker level) containing all public
declarations.

Marco Oetken writes:
> I have been thinking about the flat namespace, too. My idea was to change
> the import statement to:
> 
>   FROM package IMPORT    ident [":=" ident]
> 
> where package could be any hierarchical name. 

I get sentimental when I see the old Modula-2 syntax.  This kind of
syntactic sugar is nice for the programmer as long as the scopes of
the namespace are populated with many objects.  If the module tree is
broad (but not deep) the programmer will appreciate this.  If it is
rather deep and a single module is typically imported from a subtree,
it has little advantage.

Peter H. Froehlich writes: 
>    For example the basic collection framework for Lagoona would be
> contained in a module named "edu.uci.ics.lagoona.core.Collections"

I am not in favor of prefixing the module with a host name.  As long
as the module can not be obtained from the host I do not see any
significant advantage of this naming scheme.  Besides: People move,
hosts move, and I don't like to call my module "de.uni-kl" just
because I lived there once :-)


Back to the topics at hand:

The prefix parts of a module name are mapped to directories.  If a
module is called `foo.bar.froboz', then the actual source code would
be located in `<src-root>/foo/bar/froboz.Mod'

Stewart Greenhill writes:
> Blackbox has a subsystem naming scheme that prefixes module names with
> strings. Sub-systems are stored in sub-directories (with the same name as
> the prefix) of the Oberon root, and sub-directories within a sub-system
> have particular uses. Eg.
> 
>   Doc   - documentation
>   Rsrc  - resources (eg. dialogs, forms)
>   Mod   - source code
>   Sym   - symbol files
>   Code  - object files

Yes.  Currently I favor this approach for installed files:

  source     :  <root>/src/foo/bar/froboz.Mod
  symbol file:  <root>/sym/foo/bar/froboz.Sym
  code files :  <root>/obj/foo/bar/froboz.*
  etc.




Distribution Packages
---------------------

Hierarchical module names and packages have no connection whatsoever,
although I messed that up in my first mail.  IMO a package is a means
of distributing a set of modules, together with some simple mechanism
to get the modules installed.  A hierarchical namespace is just a way
to reduce the chance that modules from different packages step on each
others toes (names), and, more importantly, to give structure to a
larger number of modules.

A package can populate any part of the module namespace.  On the other
hand, a well behaved package called "foo-bar-7.4.1" should either
contain a module `foo.bar' or a set of modules `foo.bar.*'.

The infrastructure for package installation is distributed with the
compiler, and after installation the package itself can be
dumped--unless you want to keep its meta information around for later
updates.  Using an existing package format from the Linux world
(e.g. Debian or Red Hat) would be possible (as long as the target
directory is the same for all users), but dpkg & friends usually come
with a very elaborate infrastructure of their own which is not
available on all targets.  Writing a specialized tool in O2 is both
simpler and more efficient.




Package Versioning
------------------

My approach to versioning is rather pragmatic.  I do not suggest to
version module or class interfaces, but rather to assign numbers to
packages(!) to keep track of what set of source code is older or newer
than the other.  A package could be labeled using the numbering scheme
of libtool: CURRENT[:REVISION[:AGE]].  This permits to detect
interface changes and source revisions, and includes a simple check
for interface compatibility.

Versioning of modules interfaces might be easy if the module itself
has full control over its own interface, but gets quite complicated if
parts of the interface are inherited from foreign modules.  If module
`foo' re-exports a type `bar.T', the changes to `bar.T' also change
the interface of `foo'.

Dirk Muysers wrote:
> There are also good ideas in the Xerox Parc ILU projects, particularly
> a very good algorithm for module footprinting, that gives a globally
> unique identifier to a module which may also be used as a module
> import key.

IMO this is the best one can achieve as far as reliable versioning of
interfaces is concerned.  But even this cannot catch changes in an
interface's semantics that are not accompanied by syntactical changes
as well.  It catches all the technical aspects of the interface's
contract, which is more than can be said of the more conventional
numbering schemes.

-- mva