# 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.