Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | UnresolvedBugs |
2 | ============== | |
3 | ||
4 | Here are the places where MLton deviates from | |
5 | <:DefinitionOfStandardML:The Definition of Standard ML (Revised)> and | |
6 | the <:BasisLibrary:Basis Library>. In general, MLton complies with | |
7 | the <:DefinitionOfStandardML:Definition> quite closely, typically much | |
8 | more closely than other SML compilers (see, e.g., our list of | |
9 | <:SMLNJDeviations:SML/NJ's deviations>). In fact, the four deviations | |
10 | listed here are the only known deviations, and we have no immediate | |
11 | plans to fix them. If you find a deviation not listed here, please | |
12 | report a <:Bug:>. | |
13 | ||
14 | We don't plan to fix these bugs because the first (parsing nested | |
15 | cases) has historically never been accepted by any SML compiler, the | |
16 | second clearly indicates a problem in the | |
17 | <:DefinitionOfStandardML:Definition>, and the remaining are difficult | |
18 | to resolve in the context of MLton's implementaton of Standard ML (and | |
19 | unlikely to be problematic in practice). | |
20 | ||
21 | * MLton does not correctly parse case expressions nested within other | |
22 | matches. For example, the following fails. | |
23 | + | |
24 | [source,sml] | |
25 | ---- | |
26 | fun f 0 y = | |
27 | case x of | |
28 | 1 => 2 | |
29 | | _ => 3 | |
30 | | f _ y = 4 | |
31 | ---- | |
32 | + | |
33 | To do this in a program, simply parenthesize the case expression. | |
34 | + | |
35 | Allowing such expressions, although compliant with the Definition, | |
36 | would be a mistake, since using parentheses is clearer and no SML | |
37 | compiler has ever allowed them. Furthermore, implementing this would | |
38 | require serious yacc grammar rewriting followed by postprocessing. | |
39 | ||
40 | * MLton does not raise the `Bind` exception at run time when | |
41 | evaluating `val rec` (and `fun`) declarations that redefine | |
42 | identifiers that previously had constructor status. (By default, | |
43 | MLton does warn at compile time about `val rec` (and `fun`) | |
44 | declarations that redefine identifiers that previously had | |
45 | constructors status; see the `valrecConstr` <:MLBasisAnnotations:ML | |
46 | Basis annotation>.) For example, the Definition requires the | |
47 | following program to type check, but also (bizarelly) requires it to | |
48 | raise the `Bind` exception | |
49 | + | |
50 | [source,sml] | |
51 | ---- | |
52 | val rec NONE = fn () => () | |
53 | ---- | |
54 | + | |
55 | The Definition's behavior is obviously an error, a mismatch between | |
56 | the static semantics (rule 26) and the dynamic semantics (rule 126). | |
57 | Given the comments on rule 26 in the Definition, it seems clear that | |
58 | the authors meant for `val rec` to allow an identifier's constructor | |
59 | status to be overridden both statically and dynamically. Hence, MLton | |
60 | and most SML compilers follow rule 26, but do not follow rule 126. | |
61 | ||
62 | * MLton does not hide the equality aspect of types declared in | |
63 | `abstype` declarations. So, MLton accepts programs like the following, | |
64 | while the Definition rejects them. | |
65 | + | |
66 | [source,sml] | |
67 | ---- | |
68 | abstype t = T with end | |
69 | val _ = fn (t1, t2 : t) => t1 = t2 | |
70 | ||
71 | abstype t = T with val a = T end | |
72 | val _ = a = a | |
73 | ---- | |
74 | + | |
75 | One consequence of this choice is that MLton accepts the following | |
76 | program, in accordance with the Definition. | |
77 | + | |
78 | [source,sml] | |
79 | ---- | |
80 | abstype t = T with val eq = op = end | |
81 | val _ = fn (t1, t2 : t) => eq (t1, t2) | |
82 | ---- | |
83 | + | |
84 | Other implementations will typically reject this program, because they | |
85 | make an early choice for the type of `eq` to be `''a * ''a -> bool` | |
86 | instead of `t * t -> bool`. The choice is understandable, since the | |
87 | Definition accepts the following program. | |
88 | + | |
89 | [source,sml] | |
90 | ---- | |
91 | abstype t = T with val eq = op = end | |
92 | val _ = eq (1, 2) | |
93 | ---- | |
94 | + | |
95 | ||
96 | * MLton (re-)type checks each functor definition at every | |
97 | corresponding functor application (the compilation technique of | |
98 | defunctorization). One consequence of this implementation is that | |
99 | MLton accepts the following program, while the Definition rejects | |
100 | it. | |
101 | + | |
102 | [source,sml] | |
103 | ---- | |
104 | functor F (X: sig type t end) = struct | |
105 | val f = id id | |
106 | end | |
107 | structure A = F (struct type t = int end) | |
108 | structure B = F (struct type t = bool end) | |
109 | val _ = A.f 10 | |
110 | val _ = B.f "dude" | |
111 | ---- | |
112 | + | |
113 | On the other hand, other implementations will typically reject the | |
114 | following program, while MLton and the Definition accept it. | |
115 | + | |
116 | [source,sml] | |
117 | ---- | |
118 | functor F (X: sig type t end) = struct | |
119 | val f = id id | |
120 | end | |
121 | structure A = F (struct type t = int end) | |
122 | structure B = F (struct type t = bool end) | |
123 | val _ = A.f 10 | |
124 | val _ = B.f false | |
125 | ---- | |
126 | + | |
127 | See <!Cite(DreyerBlume07)> for more details. |