14.2 Invoking Units

The [email protected] unit has no imports, so it can be invoked directly using invoke-unit:

> (require "simple-factory-unit.rkt")
> (invoke-unit [email protected])

Factory started.

The invoke-unit form does not make the body definitions available, however, so we cannot build any toys with this factory. The define-values/invoke-unit form binds the identifiers of a signature to the values supplied by a unit (to be invoked) that implements the signature:

> (define-values/invoke-unit/infer [email protected])

Factory started.

> (build-toys 3)

(list (toy 'blue) (toy 'blue) (toy 'blue))

Since [email protected] exports the toy-factory^ signature, each identifier in toy-factory^ is defined by the define-values/invoke-unit/infer form. The /infer part of the form name indicates that the identifiers bound by the declaration are inferred from [email protected].

Now that the identifiers in toy-factory^ are defined, we can also invoke [email protected], which imports toy-factory^ to produce toy-store^:

> (require "toy-store-unit.rkt")
> (define-values/invoke-unit/infer [email protected])
> (get-inventory)

'()

> (stock! 2)
> (get-inventory)

(list (toy 'green) (toy 'green))

Again, the /infer part define-values/invoke-unit/infer determines that [email protected] imports toy-factory^, and so it supplies the top-level bindings that match the names in toy-factory^ as imports to [email protected].