Modules, defining

The primary purpose of modules is to export things for use by the importing code. A module can export:

Functions, catches, records, and opaque types can be exported by replacing the keyword define or declare with the keyword export, as in:

  export function output-header as ; ...
  export integer function next as ; ...
  export catch end-of-group
  export record myrec ...

Even though external functions can be exported, the module retains control of the functions' properties. The importer can call the function, but it cannot change the external function's mapping to an external name or library.

For example the set external function action for the function reader is only permitted inside the module defining the function reader, and not in other modules or programs that import the function.

  export external source function reader of value string file-name
    set external function of reader to "utf8Reader" in function-library "utf8filter"

Constant and global shelves can be exported by preceding the declaration with the keyword export, as in:

  export global byte-count initial {0}
  export constant readAccess initial {1}

Global variables defined in a module cannot be initialized from the command-line, even if they are exported to the main program.

What's Not Exportable

There are some kinds of properties that will always remain "private" to modules, and cannot be exported.

  • macros
  • groups
  • find rules
  • markup processing rules

Built-in names cannot be exported. Some examples of built-in names are:

Groups and Modules

Each module has its own set of groups. Independently of what they are named, no group can have rules within it from different modules. This module specificness of groups extends to the #implied group: each module has its own #implied group.

Each module has its own current group. The setting of a group within one module does not affect the current group of any other module. The default current group for a module is that module's #implied group.

The effect of the above is that rule selection always selects from within a single module. In the case of element rules, the rules are selected from the module where the "%c" (or suppress) occurs.

Markup library search paths

The main program and each module has its own #library, #libpath and #libvalue shelves. The command-line settings for these shelves are applied to every set of library shelves.

This means that supplying markup library search paths on the command-line can change the behavior of modules. This is very convenient when a module performs markup processing but does not provide for customizing the search paths.

Line-breaking rules

When a stream is opened with line breaking, the line-breaking rules used are those in the module in which the stream was opened. This is true, even when data is written to the stream in another module.