14.1 Signatures and Units
The interface of a unit is described in terms of signatures. Each signature is defined (normally within a module) using define-signature. For example, the following signature, placed in a "toy-factory-sig.ss" file, describes the exports of a component that implements a toy factory:
By convention, signature names with ^.
; In "toy-factory-sig.ss": |
|
(define-signature toy-factory^ |
(build-toys ; (integer? -> (listof toy?)) |
repaint ; (toy? symbol? -> toy?) |
toy? ; (any/c -> boolean?) |
toy-color)) ; (toy? -> symbol?) |
|
(provide toy-factory^) |
An implementation of the toy-factory^ signature is written using define-unit with an export clause that names toy-factory^:
By convention, unit names with @.
; In "simple-factory-unit.ss": |
|
(require "toy-factory-sig.ss") |
|
(define-unit simple-factory@ |
(import) |
(export toy-factory^) |
|
(printf "Factory started.\n") |
|
(define-struct toy (color) #:transparent) |
|
(define (build-toys n) |
(make-toy 'blue))) |
|
(define (repaint t col) |
(make-toy col))) |
|
(provide simple-factory@) |
The toy-factory^ signature also could be referenced by a unit that needs a toy factory to implement something else. In that case, toy-factory^ would be named in an import clause. For example, a toy store would get toys from a toy factory. (Suppose, for the sake of an example with interesting features, that the store is willing to sell only toys in a particular color.)
; In "toy-store-sig.ss": |
|
(define-signature toy-store^ |
(store-color ; (-> symbol?) |
stock! ; (integer? -> void?) |
get-inventory)) ; (-> (listof toy?)) |
|
(provide toy-store^) |
; In "toy-store-unit.ss": |
|
(require "toy-store-sig.ss" |
"toy-factory-sig.ss") |
|
(define-unit toy-store@ |
(import toy-factory^) |
(export toy-store^) |
|
|
(define (store-color) 'green) |
|
(define (maybe-repaint t) |
t |
(repaint t (store-color)))) |
|
(define (stock! n) |
(set! inventory |
(append inventory |
(map maybe-repaint |
(build-toys n))))) |
|
(define (get-inventory) inventory)) |
|
(provide toy-store@) |
Note that "toy-store-unit.ss" imports "toy-factory-sig.ss", but not "simple-factory-unit.ss". Consequently, the toy-store@ unit relies only on the specification of a toy factory, not on a specific implementation.