The module system just described is very flexible, and not only does it
allow us to model current operations and constraints on modules, it also
allows the expression of new constraints. The following
sections go into more detail on how the module system can be used.

\subsection{Composition and Information Hiding}

A module's classpath is modeled by its module imports. Imports also have the advantage
of allowing a choice in which class to load, and in causing an
ambiguous type error  when more than one bundle offers
a class instead of just loading (or failing to load) the wrong class at runtime.

The \textbf{replace} and \textbf{merge} operations allow fine-grained
definition of shared modules that is not possible with existing
module systems. The closest feature that allows similar functionality
is the OSGi \textit{uses} directive that enforces a common classloader
between packages. Merge, in particular, allows for maitaining consistency
of shared dependencies in a manner that is not supported in existing
module systems.

Replace and merge, however, are imperative operations, and it would
be desirable, or even necessary, to have some sort of module-aware 
debugging environment when errors arise. 

Given their flexibility,
there are many anti-patterns for the use of merge and replace, one of which
is directly replacing a merged member instead of using the merged reference.
Developing patterns and identifying anti-patterns for these operations will be
crucial for the successful deployment of the module system for real-world applications.

As mentioned previously, module-less classes are considered to be part 
of the ``default module'', and its singleton instance is implicitly 
imported by all modules. Completely module-less builds also work as before.
This allows for integration with existing code with little or no change.

Special lookups such as the bootclasspath and java.lang classes can be
modeled as being members of special modules (bootmodule and javalib), 
which are given preference during lookup (bootmodule first, then javalib,
then everything else using the lookup rules for modules). Membership
in these special modules will probably be implemented in a similar way to
the OSGi \textit{extends} feature.

Imports and exports are directly implemented by module imports and export package.
Section \ref{translation} details a translation from OSGi modules to
the modules proposed system. The translation itself is automatic and has been
implemented as a Java program.

Nesting is a feature that is conspicuously absent in the module system. This
is primarily because Java class nesting idiom does not transfer very well to
nested modules: nested modules are usually very tightly coupled, unlike nested
classes. This is left as future work, and there are already some proposals
and initiatives in this area, such as JSR 294 and the OSGi core expert group.

\subsection{Versioning}

Overriding can be used to model versioning. It is already done
implicitly by current usage of existing module systems: newer versions  
override past versions as long as they are backward compatible.
However, the module system allows additional constraints to be specified using
module relationships. Non-backward compatibility can be modeled by not specifying a
previous version in the overrides list.

\begin{lstlisting}[caption=Versioning Using Overrides]
//file appv1_1.module
module appv1_1;

//file appv1_2.module
//version 1.2 is backward compatible to 1.1
module appv1_2 overrides appv1_1;

//file appv2_0.module
//but version 2 is no longer backward compatible
module appv2_0; 
\end{lstlisting}

In this manner backward compatibility can now be expressed in 
and checked by the module system, instead of just being written
down in separate documentation.

Extends allows specialization and patch releases that do not contain 
the entire previous version's classes, as already demonstrated in
the previous section. However, determining when to use module
extension over existing extension patterns using classes warrant
further study.

Interfaces can also be used to model version ranges, and even feature
compatibility across versions. Versions that are in the same version 
range or are feature compatible implement the same interface.

\begin{lstlisting}[caption=Interfaces as Properties]
//file appv1.module
module appv1 implements appv1to2, supportsfeature1;...
//file appv2.module
module appv2 implements appv1to2, appv2to4, supportsfeature1;...
//file appv3.module
module appv3 implements appv2to4, supportsfeature1, supportsfeature2; ...//new feature
//file appv4.module
module appv4 implements appv2to4, supportsfeature2; ...//no longer supports feature1
\end{lstlisting}

In general, interfaces can be used as a tag for any arbitrary constraint, 
in a similar manner that empty interfaces are used in Java to mark classes 
that satisfy a certain property.

It should be noted that extends, implements and overrides are all orthogonal,
so a module can be a submodule of another module, override a set of modules and
implement a set of interfaces. This allows a module author to reuse portions
of the supermodule, specify certain properties that the module satisfies
using module interfaces, and specify a set of modules it overrides.

These extends, implements and overrides declarations do not have to be explicit.
Common usage of existing module systems mostly already assume a that a 
module overrides another module of the same name if its version 
number is higher. Existing module systems can generate these version-related interfaces 
internally, while still allowing explicit declarations for patch releases 
using extends and using module interfaces for expressing non-version
related constraints. Alternatively, weak interfaces can be modified to include
versions as part of its constraints, instead of just the set of exposed packages.
As a demonstration, section \ref{translation} shows how OSGi bundles can be
translated into modules using the methods outlined above.



\subsection{Instantiation}

Import own is derived directly from iJAM, and is improved with an explicit exporting 
mechanism and a module lookup system using module qualifiers. Singleton module instances mirror
OSGi singletons, with the additional constraint of their dependencies being unmodifiable. 
The module qualifier in type references and
imports allow fine-grained selection of the class to load in contrast
to fixed loading strategies. They also allow for module lookups relative to
a module's context, decoupling modules from globally named module instances.

However, instantiation as currently implemented is still done eagerly, pulling in all
of an imports dependencies the moment the import is instantiated. This may not be necessary,
especially when interfaces are used. A way to instantiate a module and its dependencies 
lazily would be required to reduce the number of dependencies, and is left as future work.

\subsection{Further Implications}

It must be emphasized that the syntax only represents the module system; it is not the only way
to implement it. As mentioned, overriding is already implicitly implemented
by versions. Other existing features such as loose coupling in OSGi can
also be modeled, i.e. by using weak interfaces and a generated import and replace
declaration. Section \ref{translation} shows how this is done when translating OSGi bundles to modules.

The module system's imports may also be extended using the already well-developed
constraints in existing module systems, or vice versa: weak interfaces can be extended
to include more than package signatures (e.g. OSGi's attribute matching). 

Separate compilation of modules with module interface dependencies would require
the ability to compile and lookup module qualified names during runtime. We believe
it is possible to do so with a classloader implementation of the module system. Reflection
APIs would also require the context in which the lookup should be done in addition to
the class' package and name. These are left as future work.

%Comment out, lack of space
%The overrides declaration creates synthetic modules for the overridden modules 
%if they are not present in the compilation. These modules are currently very loose,
%in that they can be assigned to a module reference of any type. Tightening the
%constraints on synthetic modules using information from overriding types is left
%as future work.
