5 More On Functors

5.1 Computed Functors

We distinguish between compiled functors and computed functors. A compiled functor is obtained by compilation of a functor definition. Computed functors are obtained by executing compiled functors whose definitions contain nested functor definitions. Compiled functors can only have lexical bindings to the data structures of the base environment. Computed functors can have lexical bindings to all data structures that the creating compiled functors supply to their definitions.

Pickled computed functors can carry computed data structures with them. This matters since

  1. a computed data structure can now be loaded together with a functor rather than being computed a new for each virtual machine using it.

  2. the functors needed to compute the carried with data structure are not needed by the virtual machine using it.

Computed functors are syntactically supported by a prepare and require section. For example, the root functor definition in the file LMF.oz can be rewritten using a prepare section as follows:

functor 
import 
   DB Form            % User defined
   System Application % System
prepare 
   Flights = 
<Sample flights>  
define 
   %% Enter some flights
   {ForAll Flights DB.add}
   ... 
end

Here the difference between the compiled functor and the computed functor is that the compiled functor contains the code to create the list of sample flights. The computed functor just contains the list itself.

All variable identifiers that are introduced in the prepare section are visible in the define section. The variables introduced by the import section are of course only visible in the define section.

The require section of a computed functors relates to the prepare section as does the import section to the define section: modules imported in the require section are available in the prepare section.

5.2 Imports

import and require specifications support features and fields. For example, in the main functor for our last minute flight booking system, we could have written the import clause for DB as follows:

DB(add getAll remove)

Besides of the documentational advantage of explicitly listing the features, the compiler tries to enforce that only listed features are used for dot access. For example, given the above import clause, the following access

DB.addd

raises an error during compilation.

In addition, also variables can be given as fields in the import specification as follows:

DB(add:Add getAll:GetAll remove)

The variables introduced for the fields interact with dynamic linking as follows: The module is requested as soon as the value for one of the variables is requested.


Denys Duchier, Leif Kornstaedt and Christian Schulte
Version 1.4.0 (20080702)