Next: Embedded Units Up: Units with Signatures Overview Previous: Linking with Signatures

## Restricting Signatures

As explained in section 7.2.2, the signature checking for a linkage requires that a provided signature exactly matches the corresponding import signature. At first glance, this requirement appears to be overly strict; it might seem that the provided signature need only satisfy the imported signature. The reason for requiring an exact match at linkages is that a `compound-unit/sig` expression is expanded into a `compound-unit` expression. Thus, the number and order of the variables used for linking must be fully known at compile-time.

The exact-match requirement does not pose any obstacle as long as a unit is linked into only one other unit. In this case, the signature specified with the unit's tag can be contrived to match the importing signature. However, a single unit may need to be linked into different units, each of which may use different importing signatures. In this case, the tag's signature must be ``bigger'' than both of the uses, and a restricting signature is explicitly provided at each linkage. The tag must satisfy every restricting signature (this is a syntactic check), and each restricting signature must exactly match the importing signature (this is a run-time check).

In the example from section 7.2.2, both `calculus@` and `gravity@` import numerical procedures, so both import the `arithmetic^` signature. However, `calculus@` does not actually need the `power` procedure to implement `integrate`; therefore, `calculus@` could be as effectively implemented in the following way:

      (define-signature simple-arithmetic^ (add subtract multiply divide))
      (define calculus@ (unit/sig calculus^ (import simple-arithmetic^) ...))

Now, the old `compound-unit/sig` expression for `model@` no longer works. Although the old expression is still syntactically correct, link-time signature checking will discover that `calculus@` expects an import matching the signature `simple-arithmetic^` but it was provided a linkage with the signature `arithmetic^`. On the other hand, changing the signature associated with `ARITHMETIC` to `simple-arithmetic^` would cause a link-time error for the linkage to `gravity@`, since it imports the `arithmetic^` signature.

The solution is to restrict the signature of `ARITHMETIC` in the linkage for `CALCULUS`:

      (define model@
        (compound-unit/sig
          (import)
          (link (ARITHMETIC : arithmetic^ (arithmetic@))
                (CALCULUS : calculus^ (calculus@ (ARITHMETIC : simple-arithmetic^))))
                (GRAPHICS : graphics^ (graphics@))
                (GRAVITY : gravity^ (gravity@ ARITHMETIC CALCULUS GRAPHICS)))
          (export (var (GRAVITY go)))))

A syntactic check will ensure that `arithmetic^` satisfies `simple-arithmetic^` (i.e., `arithmetic^` contains at least the variables of `simple-arithmetic^`). Now, all link-time signature checks will succeed, as well.

Next: Embedded Units Up: Units with Signatures Overview Previous: Linking with Signatures