File: GenerativeException

package info (click to toggle)
mlton 20130715-3
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 60,900 kB
  • ctags: 69,386
  • sloc: xml: 34,418; ansic: 17,399; lisp: 2,879; makefile: 1,605; sh: 1,254; pascal: 256; python: 143; asm: 97
file content (141 lines) | stat: -rw-r--r-- 17,203 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="AsciiDoc 8.6.8">
<title>GenerativeException</title>
<link rel="stylesheet" href="./asciidoc.css" type="text/css">
<link rel="stylesheet" href="./pygments.css" type="text/css">


<script type="text/javascript" src="./asciidoc.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
asciidoc.install();
/*]]>*/
</script>
<link rel="stylesheet" href="./mlton.css" type="text/css"/>
</head>
<body class="article">
<div id="banner">
<div id="banner-home">
<a href="./Home">MLton 20130715</a>
</div>
</div>
<div id="header">
<h1>GenerativeException</h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>In <a href="StandardML">Standard ML</a>, exception declarations are said to be
<em>generative</em>, because each time an exception declaration is evaluated,
it yields a new exception.</p></div>
<div class="paragraph"><p>The following program demonstrates the generativity of exceptions.</p></div>
<div class="listingblock">
<div class="content"><div class="highlight"><pre><span class="k">exception</span><span class="w"> </span><span class="n">E</span><span class="w"></span>
<span class="k">val</span><span class="w"> </span><span class="n">e1</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">E</span><span class="w"></span>
<span class="k">fun</span><span class="w"> </span><span class="n">isE1</span><span class="w"> </span><span class="p">(</span><span class="n">e</span><span class="p">:</span><span class="w"> </span><span class="n">exn</span><span class="p">):</span><span class="w"> </span><span class="n">bool</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
<span class="w">   </span><span class="k">case</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="k">of</span><span class="w"></span>
<span class="w">      </span><span class="n">E</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">true</span><span class="w"></span>
<span class="w">    </span><span class="p">|</span><span class="w"> </span><span class="p">_</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">false</span><span class="w"></span>
<span class="k">exception</span><span class="w"> </span><span class="n">E</span><span class="w"></span>
<span class="k">val</span><span class="w"> </span><span class="n">e2</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">E</span><span class="w"></span>
<span class="k">fun</span><span class="w"> </span><span class="n">isE2</span><span class="w"> </span><span class="p">(</span><span class="n">e</span><span class="p">:</span><span class="w"> </span><span class="n">exn</span><span class="p">):</span><span class="w"> </span><span class="n">bool</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
<span class="w">   </span><span class="k">case</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="k">of</span><span class="w"></span>
<span class="w">      </span><span class="n">E</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">true</span><span class="w"></span>
<span class="w">    </span><span class="p">|</span><span class="w"> </span><span class="p">_</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">false</span><span class="w"></span>
<span class="k">fun</span><span class="w"> </span><span class="n">pb</span><span class="w"> </span><span class="p">(</span><span class="n">b</span><span class="p">:</span><span class="w"> </span><span class="n">bool</span><span class="p">):</span><span class="w"> </span><span class="n">unit</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
<span class="w">   </span><span class="n">print</span><span class="w"> </span><span class="p">(</span><span class="n">concat</span><span class="w"> </span><span class="p">[</span><span class="n">Bool</span><span class="p">.</span><span class="n">toString</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">])</span><span class="w"></span>
<span class="k">val</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">(</span><span class="n">pb</span><span class="w"> </span><span class="p">(</span><span class="n">isE1</span><span class="w"> </span><span class="n">e1</span><span class="p">)</span><span class="w"></span>
<span class="w">          </span><span class="p">;</span><span class="n">pb</span><span class="w"> </span><span class="p">(</span><span class="n">isE1</span><span class="w"> </span><span class="n">e2</span><span class="p">)</span><span class="w"></span>
<span class="w">          </span><span class="p">;</span><span class="w"> </span><span class="n">pb</span><span class="w"> </span><span class="p">(</span><span class="n">isE2</span><span class="w"> </span><span class="n">e1</span><span class="p">)</span><span class="w"></span>
<span class="w">          </span><span class="p">;</span><span class="w"> </span><span class="n">pb</span><span class="w"> </span><span class="p">(</span><span class="n">isE2</span><span class="w"> </span><span class="n">e2</span><span class="p">))</span><span class="w"></span>
</pre></div></div></div>
<div class="paragraph"><p>In the above program, two different exception declarations declare an
exception <span class="monospaced">E</span> and a corresponding function that returns <span class="monospaced">true</span> only on
that exception.  Although declared by syntactically identical
exception declarations, <span class="monospaced">e1</span> and <span class="monospaced">e2</span> are different exceptions.  The
program, when run, prints <span class="monospaced">true</span>, <span class="monospaced">false</span>, <span class="monospaced">false</span>, <span class="monospaced">true</span>.</p></div>
<div class="paragraph"><p>A slight modification of the above program shows that even a single
exception declaration yields a new exception each time it is
evaluated.</p></div>
<div class="listingblock">
<div class="content"><div class="highlight"><pre><span class="k">fun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="p">():</span><span class="w"> </span><span class="n">exn</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="p">(</span><span class="n">exn</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">bool</span><span class="p">)</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
<span class="w">   </span><span class="k">let</span><span class="w"></span>
<span class="w">      </span><span class="k">exception</span><span class="w"> </span><span class="n">E</span><span class="w"></span>
<span class="w">   </span><span class="k">in</span><span class="w"></span>
<span class="w">      </span><span class="p">(</span><span class="n">E</span><span class="p">,</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">true</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">_</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">false</span><span class="p">)</span><span class="w"></span>
<span class="w">   </span><span class="k">end</span><span class="w"></span>
<span class="k">val</span><span class="w"> </span><span class="p">(</span><span class="n">e1</span><span class="p">,</span><span class="w"> </span><span class="n">isE1</span><span class="p">)</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="p">()</span><span class="w"></span>
<span class="k">val</span><span class="w"> </span><span class="p">(</span><span class="n">e2</span><span class="p">,</span><span class="w"> </span><span class="n">isE2</span><span class="p">)</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="p">()</span><span class="w"></span>
<span class="k">fun</span><span class="w"> </span><span class="n">pb</span><span class="w"> </span><span class="p">(</span><span class="n">b</span><span class="p">:</span><span class="w"> </span><span class="n">bool</span><span class="p">):</span><span class="w"> </span><span class="n">unit</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
<span class="w">   </span><span class="n">print</span><span class="w"> </span><span class="p">(</span><span class="n">concat</span><span class="w"> </span><span class="p">[</span><span class="n">Bool</span><span class="p">.</span><span class="n">toString</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">])</span><span class="w"></span>
<span class="k">val</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">(</span><span class="n">pb</span><span class="w"> </span><span class="p">(</span><span class="n">isE1</span><span class="w"> </span><span class="n">e1</span><span class="p">)</span><span class="w"></span>
<span class="w">          </span><span class="p">;</span><span class="w"> </span><span class="n">pb</span><span class="w"> </span><span class="p">(</span><span class="n">isE1</span><span class="w"> </span><span class="n">e2</span><span class="p">)</span><span class="w"></span>
<span class="w">          </span><span class="p">;</span><span class="w"> </span><span class="n">pb</span><span class="w"> </span><span class="p">(</span><span class="n">isE2</span><span class="w"> </span><span class="n">e1</span><span class="p">)</span><span class="w"></span>
<span class="w">          </span><span class="p">;</span><span class="w"> </span><span class="n">pb</span><span class="w"> </span><span class="p">(</span><span class="n">isE2</span><span class="w"> </span><span class="n">e2</span><span class="p">))</span><span class="w"></span>
</pre></div></div></div>
<div class="paragraph"><p>Each call to <span class="monospaced">f</span> yields a new exception and a function that returns
<span class="monospaced">true</span> only on that exception.  The program, when run, prints <span class="monospaced">true</span>,
<span class="monospaced">false</span>, <span class="monospaced">false</span>, <span class="monospaced">true</span>.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_type_safety">Type Safety</h2>
<div class="sectionbody">
<div class="paragraph"><p>Exception generativity is required for type safety.  Consider the
following valid SML program.</p></div>
<div class="listingblock">
<div class="content"><div class="highlight"><pre><span class="k">fun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="p">():</span><span class="w"> </span><span class="p">(</span><span class="n">&#39;a</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">exn</span><span class="p">)</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="p">(</span><span class="n">exn</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">&#39;a</span><span class="p">)</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
<span class="w">   </span><span class="k">let</span><span class="w"></span>
<span class="w">      </span><span class="k">exception</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">&#39;a</span><span class="w"></span>
<span class="w">   </span><span class="k">in</span><span class="w"></span>
<span class="w">      </span><span class="p">(</span><span class="n">E</span><span class="p">,</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">_</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="k">raise</span><span class="w"> </span><span class="n">Fail</span><span class="w"> </span><span class="s">&quot;f&quot;</span><span class="p">)</span><span class="w"></span>
<span class="w">   </span><span class="k">end</span><span class="w"></span>
<span class="k">fun</span><span class="w"> </span><span class="n">cast</span><span class="w"> </span><span class="p">(</span><span class="n">a</span><span class="p">:</span><span class="w"> </span><span class="n">&#39;a</span><span class="p">):</span><span class="w"> </span><span class="n">&#39;b</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
<span class="w">   </span><span class="k">let</span><span class="w"></span>
<span class="w">      </span><span class="k">val</span><span class="w"> </span><span class="p">(</span><span class="n">make</span><span class="p">:</span><span class="w"> </span><span class="n">&#39;a</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">exn</span><span class="p">,</span><span class="w"> </span><span class="p">_)</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="p">()</span><span class="w"></span>
<span class="w">      </span><span class="k">val</span><span class="w"> </span><span class="p">(_,</span><span class="w"> </span><span class="n">get</span><span class="p">:</span><span class="w"> </span><span class="n">exn</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">&#39;b</span><span class="p">)</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="p">()</span><span class="w"></span>
<span class="w">   </span><span class="k">in</span><span class="w"></span>
<span class="w">      </span><span class="n">get</span><span class="w"> </span><span class="p">(</span><span class="n">make</span><span class="w"> </span><span class="n">a</span><span class="p">)</span><span class="w"></span>
<span class="w">   </span><span class="k">end</span><span class="w"></span>
<span class="k">val</span><span class="w"> </span><span class="p">_</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">((</span><span class="n">cast</span><span class="w"> </span><span class="mi">13</span><span class="p">):</span><span class="w"> </span><span class="n">int</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">int</span><span class="p">)</span><span class="w"> </span><span class="mi">14</span><span class="w"></span>
</pre></div></div></div>
<div class="paragraph"><p>If exceptions weren&#8217;t generative, then each call <span class="monospaced">f ()</span> would yield
the same exception constructor <span class="monospaced">E</span>.  Then, our <span class="monospaced">cast</span> function could
use <span class="monospaced">make: 'a -&gt; exn</span> to convert any value into an exception and then
<span class="monospaced">get: exn -&gt; 'b</span> to convert that exception to a value of arbitrary
type.  If <span class="monospaced">cast</span> worked, then we could cast an integer as a function
and apply.  Of course, because of generative exceptions, this program
raises <span class="monospaced">Fail "f"</span>.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_applications">Applications</h2>
<div class="sectionbody">
<div class="paragraph"><p>The <span class="monospaced">exn</span> type is effectively a <a href="UniversalType">universal type</a>.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_also_see">Also see</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
<a href="GenerativeDatatype">GenerativeDatatype</a>
</p>
</li>
</ul></div>
</div>
</div>
</div>
<div id="footnotes"><hr></div>
<div id="footer">
<div id="footer-text">
</div>
<div id="footer-badges">
</div>
</div>
</body>
</html>