|
|
1.1 root 1: What are the meaning of "local" and "open" in signatures?
2:
3: David B. MacQueen
4:
5: I am not sure what the purpose of the local spec form was supposed to be.
6: Specifications such as
7:
8: local val x : t
9: in val y : s
10: end
11:
12: are certainly useless, and
13:
14: local type t
15: in val x : t
16: end
17:
18: does not seem very interesting either. Presumably the purpose of local specs
19: was to localize the scope of open specs, as in
20:
21: structure A : sig type t ... end
22: local open A
23: in val x : t
24: end
25:
26: But I would argue that open specs are really just an abbreviation device and
27: do not add specifications to a signature in any case. The bindings in a
28: structure, such as A above, are a different kind of entity from normal
29: signature specifications, and they can be treated differently from
30: specifications. It makes sense to include the specifications in a signature
31: in another signature, as is done by the include spec, but it does not make
32: sense to include the components of a structure in a signature. For instance,
33: consider the following example:
34:
35: structure A = struct type t = int val x = 3 end
36: signature SIG =
37: sig
38: open A
39: end
40:
41: What is the meaning of SIG? Since the unconstrained structure A matches
42: many different signatures, it would seem that SIG is not well defined.
43:
44: As we have implemented the open specification, it simply makes
45: the identifiers inside the opened structures visible in unqualified form, so
46: that "t" can be used as an abbreviation for "A.t" in the above example. The
47: scope of the open specification is by default the remainder of the signature
48: expression, and an open specification does not add any new components to a
49: signature. Thus the above definition of SIG is equivalent to
50:
51: signature SIG = sig end
52:
53: This view of open specs seems to eliminate any justification for local
54: specs, so they are suppored only in a dummy form for compatibility. The
55: meaning of
56:
57: local spec1 in spec2 end
58:
59: is the same as
60:
61: spec1 spec2
62:
63: except that the specifications in spec1 are ignored during signature
64: matching. If spec1 is an open spec, which is the only reasonable
65: possibility, the open spec remains in force even after the end of the local
66: spec. For instance,
67:
68: sig
69: structure A : sig type t ... end
70: type t
71: local open A in
72: in val x : t (* t is A.t *)
73: end
74: val y : t (* t is still A.t, not the top level t *)
75: end
76:
77: We would be interested to hear any arguments against this treatment. If it
78: is generally accepted, it would seem to make sense to delete local specs from
79: the language. In any case, it should be considered a dubious feature to be
80: used only when necessary for compatibility. I also consider the let
81: structure expression a dubious feature, but it is at least fairly simple to
82: implement.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.