!!! Use Case

Packages should enable:

* Combining libraries with conflicting names
* Resolving abstract library paths to filesystem paths
* Abstracting over an implementation at compile time

The essential technical difference between packages and [Modules] is that packages enable compile-time instantiation and composition while modules enable run-time instantiation and composition.

!!! PLT Scheme Modules/Components

!! Module System

PLT Scheme's module system is a basic __namespace__ and inclusion system similar to that of Haskell or Java, ignoring issues related to macros and the REPL. The module system is intended to provide a very basic, low-level framework upon which more advanced component systems can be built.

A module has the basic form:
(module <module-name> <language>
  (require <module-path> ...)
  (provide <exported-name> ...)
  <module-body> ...)

;{{<module-name>}}: should provide a unique name for the module in the compilation environment. We can ignore {{<language>}}, as it is primarily relevant to macro-expansion.
;{{<module-path>}}: typically specifies a path to the file containing the module to import, although variations allow you to explicitly reference modules in the standard library or an external repository (~PLaneT). In addition you may restrict the names imported from the module, and rename the imported names in various ways.
;{{<exported-name>}}: allows you to specify the names (declarations, top-level variables, etc) to be exported. The set of exported names can be restricted and renamed in various ways.

Unlike Orc's {{include}} declaration or Python's {{import}} -- but like Java's {{import}} -- modules which are required multiple times are only instantiated once. All references to the module alias the same set of names.

Modules do not support mutual (circular) dependencies or separate compilation. Because of the one-instantiation-per-module policy, modules cannot quite be implemented as straightforward textual inclusion, but something very close is feasible.  Certainly it is possible to compile any program using modules into one which does not.

!! Units and Signatures

PLT Scheme provides a system on top of modules designed to support componentization and separate compilation. The key idea is that a __component__ is separated into a __signature__ (which provides a compile-time view of the component) and a __unit__ (which provides the run-time implementation the signature). This is similar to the separation in C between {{.h}} header files and {{.c}} implementation files.

To compile a unit, you only need the signatures of the components it depends on. This allows separate compilation and therefore compilation of components with mutual (circular) dependencies.

A unit which depends on a signature can be __linked__ to another unit which implements that signature, forming a larger unit with fewer dependencies. A unit can even be linked to itself to satisfy circular dependencies. An executable program is created by linking together units to create a unit with no dependencies.

Units and signatures continue to use the lower-level module system in order to handle namespaces and imports -- for example, signatures and units are typically defined inside modules, and the module-level require mechanism is used to import signatures for use in defining units.

In implementation, units are very similar to Java packages -- although Java does not have any concept of the interface or signature of a component, it is possible to create packages serving this role, which contain only interfaces or dummy classes with no implementation. A key difference is that the dependencies, compilation, and linking of units are more explicitly under the control of the programmer compared to Java packages, which rely on class loaders (and therefore the classpath) to implicitly handle linking.

!! Summary

In my opinion, Orc needs something which combines aspects of modules and units/signatures, in much the same way Java packages do. It should be possible to create components with mutual dependencies, and also possible to compile components separately when desired. However it should not be necessary to separate interface from implementation in cases where this has no benefit.

Implicit in the PLT perspective is that modules and units don't affect the run-time behavior of programs; they are purely compile-time entities.  I find the simplicity of this approach very compelling, however in a concurrent language there may be reasons to isolate modules from each other at run-time in some ways.