1.4 Modules
All of the examples shown so far have been “loose M” that is taken out of context. To write a legal M program, all source text must appear in the context of a module definition. A module defines a top-level namespace for any type names that are defined. A module also defines a scope for defining extents that will store actual values, as well as computed values.
Here is a simple module definition:
module Geometry { // declare a type type Point { X : Integer; Y : Integer; } // declare some extents Points : Point*; Origin : Point; // declare a computed value TotalPointCount { Points.Count + 1; } }
In this example, the module defines one type named Geometry.Point. This type describes what point values will look like, but doesn’t mention any locations where those values can be stored.
This example also includes two module-scoped extents (Points and Origin). Module-scoped field declarations are identical in syntax to those used in entity types. However, fields declared in an entity type simply name the potential for storage once an extent has been determined; in contrast, fields declared at module-scope name actual storage that must be mapped by an implementation to load and interpret the module.
Modules may refer to declarations in other modules by using an import directive to name the module containing the referenced declarations. For a declaration to be referenced by other modules, the declaration must be explicitly exported using an export directive.
Consider this module:
module MyModule { import HerModule; // declares HerType export MyType1; export MyExtent1; type MyType1 : Logical*; type MyType2 : HerType; MyExtent1 : Number*; MyExtent2 : HerType; }
Note that only MyType1 and MyExtent1 are visible to other modules. This makes the following definition of HerModule legal:
module HerModule { import MyModule; // declares MyType1 and MyExtent1 export HerType; type HerType : Text where value.Count < 100; type Private : Number where !(value in MyExtent1); SomeStorage : MyType1; }
As this example shows, modules may have circular dependencies.