|
|
1.1 root 1: \chapter{Modules}
2: ML provides a powerful module system, which can be used to partition
3: programs along clean interfaces.
4:
5: \section{Structures}
6:
7: In its simplest form, a module is
8: (syntactically) just a collection of declarations viewed as a unit,
9: or (semantically) the environment defined by those definitions.
10: This is one form of a {\em structure--expression}:
11: \verb"struct"~dec~\verb"end". For example, the following structure--expression represents an implementation of stacks:
12: \begin{verbatim}
13: struct
14: datatype 'a stack = Empty | Push of 'a * 'a stack
15: exception Pop and Top
16: fun empty(Empty) = true | empty _ = false
17: val push = Push
18: fun pop(Push(v,s)) = s | pop(Empty) = raise Pop
19: fun top(Push(v,s)) = v | top(Empty) = raise Top
20: end
21: \end{verbatim}
22: Structure--expressions and ordinary expressions are distinct classes;
23: structure--expressions may be bound using the \verb"structure"
24: keyword to structure--names, while ordinary expressions are
25: bound using \verb"val" to value--variables.
26: The form of a \verb"structure" binding is as follows:
27: \begin{quote}
28: \verb"structure" name \verb"=" structure--expression
29: \end{quote}
30: Thus, we might make a structure Stack using the structure--expression
31: shown above:
32: \begin{verbatim}
33: structure Stack = struct
34: datatype . . .
35: exception . . .
36: . . .
37: end
38: \end{verbatim}
39:
40: The environment $E$ that binds the identifiers \verb"stack",
41: \verb"Pop", \verb"empty", etc. is now itself bound to the
42: structure--identifier \verb"Stack". To refer to names in $E$, {\em
43: qualified identifiers} must be used. A qualified identifier consists
44: of a structure--name, a dot, and the name of a structure component,
45: e.g. \verb"Stack.empty" (a value), \verb"Stack.stack" (a type),
46: \verb"Stack.Pop" (an exception), etc.
47:
48: {\bf Structure closure:} In order to isolate the interface between a
49: structure and its context, a \verb"struct" phrase is not allowed to
50: contain global references to types, values, or exceptions, except for
51: pervasive primitives of the language like \verb"int", \verb"nil",
52: etc. It can, however, contain global references to other structures,
53: signatures, and functors, including qualified names referring to
54: compenents (values, types, etc.) of other structures.
55:
56: There are three forms of structure-expression:
57: \begin{enumerate}
58: \item An environment enclosed in \verb"struct" ... \verb"end" (as
59: above),
60:
61: \item An identifer that has been previously bound in a
62: \verb"structure" declaration, and
63:
64: \item A functor application \verb"F("{\it str}\verb")", where
65: \verb"F" is the name of a functor and {\it str} is a structure
66: expression.
67: \end{enumerate}
68: Thus, the declaration \verb"structure~Pushdown~=~Stack" binds the
69: name \verb"Pushdown" to the same structure that \verb"Stack" is bound
70: to; here, \verb"Stack" is an example of the second kind of structure
71: expression.
72:
73: \subsection{Accessing structure components}
74: The bindings making up a structure define named {\em components} of
75: the structure, as in a record. To refer to such components we use
76: qualified names, which are formed by appending a period followed by a
77: component name to the name of a structure. For instance,
78: \verb"Stack.empty" refers to the function \verb"empty" defined in the
79: structure \verb"Stack". If the qualified name designates a
80: substructure of a structure, then it too has components; {\em e.g.}
81: \verb"A.B.x" denotes the component \verb"x" of the substructure
82: \verb"B" of a structure \verb"A".
83:
84: Qualifiers can be attached only to names; they do not apply to other
85: forms of structure expressions. Qualified names are treated as
86: single lexical units; the dot is not an infix operator.
87:
88: Direct access to the bindings of a structure is provided by the
89: \verb"open" declaration, which is analagous to the ``with'' clause of
90: Pascal. For example, in the scope (determined in the usual way) of
91: the declaration
92: \begin{quote}
93: \verb"open Stack"
94: \end{quote}
95: the names \verb"stack", \verb"empty", \verb"pop", etc. refer to the
96: corresponding components of the \verb"Stack" structure. It is as
97: though the body of the structure definition had been inserted in the
98: program at that point, except that the bindings are not recreated,
99: but are instead simply ``borrowed'' from the opened structure.
100: \verb"open" declarations follow the usual rules for visibility, so
101: that if \verb"A" and \verb"B" are two structures containing a binding
102: for \verb"x" (of the same flavor, of course), then after opening both
103: \verb"A" and \verb"B" with the declaration
104: \begin{quote}
105: \verb"open A" \\
106: \verb"open B"
107: \end{quote}
108: the unqualified identifier \verb"x" will be equivalent to
109: \verb"B.x". The \verb"x" component of \verb"A" can still be referred
110: to as \verb"A.x", unless \verb"B" also contains a substructure named
111: \verb"A".
112:
113: Qualified identifiers do not have infix status. If \verb"+" is
114: declared infix in a structure \verb"A", the qualified identifier
115: \verb"A.+" is not an infix identifier. However, when an identifier
116: is made visible by opening a structure, it retains its infix status,
117: if any. AMBIGUOUS.
118:
119: The declaration \verb"open A B C" is equivalent to \verb"open A; open
120: B; open C".
121:
122: \subsection{Evaluating structure expressions}
123: The evaluation of a structure expression {\em str} depends on its
124: form, and assumes a current structure environment $SE$ that binds
125: structures and functors to names. Informally, evaluation proceeds as
126: follows:
127: \begin{enumerate}
128: \item If {\em str} is an encapsulated declaration ({\it i.e.}
129: \verb"struct"...\verb"end"), then the body declarations are evaluated
130: relative to $SE$ and the {\em pervasive} value, exception, and type
131: environments of ML (that is, the environments binding the built-in
132: primitives of the language). The resulting environment is packaged
133: as a structure and returned. The evaluation of value bindings may
134: have an effect on the store (the mapping of references to contents);
135: the new store is returned as well, to be used in subsequent
136: expression evaluations.
137:
138: \item If {\em str} is a simple name, then its binding in $SE$ is
139: returned. If it is qualified name, then it is used as an access path
140: starting with $SE$ and the designated substructure is returned.
141:
142: \item If {\em str} is a functor application
143: \verb"F("~$str'$~\verb")", where the functor \verb"F" is declared
144: by \verb"functor F ( A ) = "~$body$,
145: the parameter structure $str'$ is
146: evaluated in $SE$ yielding structure $s_1$; then the ``body'' of the
147: definition of \verb"M", which is a structure expression, is evaluated
148: in $SE+\{A \mapsto s_1 \}$. In other words, functor applications are
149: evaluated in a conventional call-by-value fashion.
150: \end{enumerate}
151:
152: \subsection{Evaluating structure declarations}
153: To evaluate a simple structure declaration, one evaluates the
154: defining structure expression in the current environment $SE$ and
155: returns the binding of the name of the left hand side to the
156: resulting structure. If evaluation of a structure expression raises
157: an (untrapped) exception, then the declaration has no effect.
158:
159: \subsection{Structure equivalence}
160: For certain purposes, such as checking sharing constraints
161: (Section~\ref{sharing}) we must be able to determine whether two
162: (references to) structures are equal or ``the same.'' Here
163: structures are treated somewhat like datatypes; each evaluation of an
164: encapsulated declaration or functor application creates a distinct
165: new structure, and all references to this structure are considered
166: equal. Thus after the following declarations:
167: \begin{verbatim}
168: structure S1 = struct ... end
169: structure S2 = S1
170: structure S3 = struct val x = 4 end
171: structure S4 = struct val x = 4 end
172: \end{verbatim}
173: the names \verb"S1" and \verb"S2" refer to the same structure and are
174: ``equal,'' whereas \verb"S3" and \verb"S4" are different structures
175: and are not equal, even though the right-hand-sides are identical.
176:
177: \section{Signatures}
178: It is often useful to explicitly constrain a structure binding to
179: limit the visibility of its fields. This is done with a {\em
180: signature}, which is to a structure binding as a type constraint is to a
181: value binding. For example, we might write a signature for the
182: \verb"Stack" module as
183: \begin{verbatim}
184: sig type 'a stack
185: exception Pop and Top
186: val Empty : 'a stack
187: val push : 'a * 'a stack -> 'a stack
188: val empty : 'a stack -> bool
189: val pop : 'a stack -> 'a stack
190: val top : 'a stack -> 'a
191: end
192: \end{verbatim}
193: The signature mentions the structure components that will be visible
194: outside the structure.
195:
196: Signatures may be bound to identifiers by a signature declaration,
197: \begin{quote}
198: \verb"signature" {\it sig-Id} \verb"=" {\it sig-expr}
199: \end{quote}
200: where {\it sig-Id} is an identifier and {\it sig-expr} is a signature
201: expression---either a \verb"sig"...\verb"end" phrase or a previously
202: bound signature identifier. Thus, the signature above could be bound
203: to the identifier \verb"STACK" by the declaration
204: \begin{verbatim}
205: signature STACK =
206: sig type 'a stack
207: exception Pop and Top
208: . . .
209: end
210: \end{verbatim}
211:
212: A signature can be used to constrain a structure by including it in a
213: structure declaration:
214: \begin{quote}
215: \verb"structure" {\it str-id} \verb":" {\it sig-expr} \verb"=" {\it str}
216: \end{quote}
217: For example, we could write
218: \begin{verbatim}
219: structure Stack1 : STACK = Stack
220: \end{verbatim}
221: Now the constructor \verb"Push" is not a visible component of the
222: \verb"Stack1" structure, since it doesn't appear in the signature;
223: the qualified identifier \verb"Stack1.Push" is erroneous.
224: Furthermore, since \verb"stack" is mentioned in the signature only as
225: a \verb"type" constructor and not as a \verb"datatype" constructor,
226: the identifier \verb"Stack1.stack" is usable as a type but not a datatype.
227: Finally, since the constructor \verb"Empty" is mentioned as a
228: \verb"val" in the signature, but not as a constructor ({\it i.e.} as
229: part of a datatype specification), then \verb"Stack1.Empty" may be
230: applied as a function but not matched in a pattern.
231:
232: There are many signatures that can match the structure \verb"Stack".
233: One of the ``broadest'' is
234: \begin{verbatim}
235: structure Stack2 : sig
236: datatype 'a stack = Empty | Push of 'a * 'a stack
237: exception Pop and Top
238: val empty : 'a stack -> bool
239: val push : 'a * 'a stack -> 'a stack
240: val pop : 'a stack -> 'a stack
241: val top : 'a stack -> 'a
242: end
243: = Stack
244: \end{verbatim}
245: and the ``narrowest'' is
246: \begin{verbatim}
247: structure Stack3 : sig end = Stack
248: \end{verbatim}
249: Now, the structure \verb"Stack2" is equivalent to \verb"Stack"; it is
250: the ``same'' structure, and all the same fields are visible. The
251: structure \verb"Stack3" has no components; there are no qualified
252: identifiers beginning with \verb"Stack3." However, \verb"Stack3" is
253: the ``same'' for structure-equivalence purposes as \verb"Stack",
254: \verb"Stack1", and \verb"Stack2"; signature constraints do not change
255: the identity of a structure, just which fields are visible.
256:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.