/usr/share/doc/mlton/guide/GenerativeException is in mlton-doc 20100608-5.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 142 143 144 145 146 147 148 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta name="robots" content="index,nofollow">
<title>GenerativeException - MLton Standard ML Compiler (SML Compiler)</title>
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="all" href="common.css">
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="screen" href="screen.css">
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="print" href="print.css">
<link rel="Start" href="Home">
</head>
<body lang="en" dir="ltr">
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-833377-1";
urchinTracker();
</script>
<table bgcolor = lightblue cellspacing = 0 style = "border: 0px;" width = 100%>
<tr>
<td style = "
border: 0px;
color: darkblue;
font-size: 150%;
text-align: left;">
<a class = mltona href="Home">MLton MLTONWIKIVERSION</a>
<td style = "
border: 0px;
font-size: 150%;
text-align: center;
width: 50%;">
GenerativeException
<td style = "
border: 0px;
text-align: right;">
<table cellspacing = 0 style = "border: 0px">
<tr style = "vertical-align: middle;">
</table>
<tr style = "background-color: white;">
<td colspan = 3
style = "
border: 0px;
font-size:70%;
text-align: right;">
<a href = "Home">Home</a>
<a href = "TitleIndex">Index</a>
</table>
<div id="content" lang="en" dir="ltr">
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>
The following program demonstrates the generativity of exceptions.
<pre class=code>
<B><FONT COLOR="#A020F0">exception</FONT></B><B><FONT COLOR="#228B22"> <FONT COLOR="#B8860B">E</FONT>
</FONT></B><B><FONT COLOR="#A020F0">val</FONT></B> e1 = E
<B><FONT COLOR="#A020F0">fun</FONT></B> isE1 (e: exn): bool =
<B><FONT COLOR="#A020F0">case</FONT></B> e <B><FONT COLOR="#A020F0">of</FONT></B>
E => true
| _ => false
<B><FONT COLOR="#A020F0">exception</FONT></B><B><FONT COLOR="#228B22"> <FONT COLOR="#B8860B">E</FONT>
</FONT></B><B><FONT COLOR="#A020F0">val</FONT></B> e2 = E
<B><FONT COLOR="#A020F0">fun</FONT></B> isE2 (e: exn): bool =
<B><FONT COLOR="#A020F0">case</FONT></B> e <B><FONT COLOR="#A020F0">of</FONT></B>
E => true
| _ => false
<B><FONT COLOR="#A020F0">fun</FONT></B> pb (b: bool): unit =
print (concat [Bool.toString b, <B><FONT COLOR="#BC8F8F">"\n"</FONT></B>])
<B><FONT COLOR="#A020F0">val</FONT></B> () = (pb (isE1 e1)
;pb (isE1 e2)
; pb (isE2 e1)
; pb (isE2 e2))
</PRE>
In the above program, two different exception declarations declare an exception <tt>E</tt> and a corresponding function that returns <tt>true</tt> only on that exception. Although declared by syntactically identical exception declarations, <tt>e1</tt> and <tt>e2</tt> are different exceptions. The program, when run, prints <tt>true</tt>, <tt>false</tt>, <tt>false</tt>, <tt>true</tt>.
</p>
<p>
A slight modification of the above program shows that even a single exception declaration yields a new exception each time it is evaluated.
<pre class=code>
<B><FONT COLOR="#A020F0">fun</FONT></B> f (): exn * (exn -> bool) =
<B><FONT COLOR="#A020F0">let</FONT></B>
<B><FONT COLOR="#A020F0">exception</FONT></B><B><FONT COLOR="#228B22"> <FONT COLOR="#B8860B">E</FONT>
</FONT></B><B><FONT COLOR="#A020F0">in</FONT></B>
(E, <B><FONT COLOR="#A020F0">fn</FONT></B> E => true | _ => false)
<B><FONT COLOR="#A020F0">end</FONT></B>
<B><FONT COLOR="#A020F0">val</FONT></B> (e1, isE1) = f ()
<B><FONT COLOR="#A020F0">val</FONT></B> (e2, isE2) = f ()
<B><FONT COLOR="#A020F0">fun</FONT></B> pb (b: bool): unit =
print (concat [Bool.toString b, <B><FONT COLOR="#BC8F8F">"\n"</FONT></B>])
<B><FONT COLOR="#A020F0">val</FONT></B> () = (pb (isE1 e1)
; pb (isE1 e2)
; pb (isE2 e1)
; pb (isE2 e2))
</PRE>
Each call to <tt>f</tt> yields a new exception and a function that returns <tt>true</tt> only on that exception. The program, when run, prints <tt>true</tt>, <tt>false</tt>, <tt>false</tt>, <tt>true</tt>.
</p>
<h2 id="head-86469abfaa44f69bd741f559ff1bb935309ad35e">Type Safety</h2>
<p>
Exception generativity is required for type safety. Consider the following valid SML program.
<pre class=code>
<B><FONT COLOR="#A020F0">fun</FONT></B> f (): ('a -> exn) * (exn -> 'a) =
<B><FONT COLOR="#A020F0">let</FONT></B>
<B><FONT COLOR="#A020F0">exception</FONT></B><B><FONT COLOR="#228B22"> <FONT COLOR="#B8860B">E</FONT> <B><FONT COLOR="#A020F0">of</FONT></B> 'a
</FONT></B><B><FONT COLOR="#A020F0">in</FONT></B>
(E, <B><FONT COLOR="#A020F0">fn</FONT></B> E x => x | _ => <B><FONT COLOR="#A020F0">raise</FONT></B> Fail <B><FONT COLOR="#BC8F8F">"f"</FONT></B>)
<B><FONT COLOR="#A020F0">end</FONT></B>
<B><FONT COLOR="#A020F0">fun</FONT></B> cast (a: 'a): 'b =
<B><FONT COLOR="#A020F0">let</FONT></B>
<B><FONT COLOR="#A020F0">val</FONT></B> (make: 'a -> exn, _) = f ()
<B><FONT COLOR="#A020F0">val</FONT></B> (_, get: exn -> 'b) = f ()
<B><FONT COLOR="#A020F0">in</FONT></B>
get (make a)
<B><FONT COLOR="#A020F0">end</FONT></B>
<B><FONT COLOR="#A020F0">val</FONT></B> _ = ((cast <B><FONT COLOR="#5F9EA0">13</FONT></B>): int -> int) <B><FONT COLOR="#5F9EA0">14</FONT></B>
</PRE>
</p>
<p>
If exceptions weren't generative, then each call <tt>f ()</tt> would yield the same exception constructor <tt>E</tt>. Then, our <tt>cast</tt> function could use <tt>make: 'a -> exn</tt> to convert any value into an exception and then <tt>get: exn -> 'b</tt> to convert that exception to a value of arbitrary type. If <tt>cast</tt> worked, then we could cast an integer as a function and apply. Of course, because of generative exceptions, this program raises <tt>Fail "f"</tt>.
</p>
<h2 id="head-76c74bd071dd73f01696fddbbffc77712a479faf">Applications</h2>
<p>
The <tt>exn</tt> type is effectively a <a href="UniversalType">universal type</a>.
</p>
<h2 id="head-a4bc8bf5caf54b18cea9f58e83dd4acb488deb17">Also see</h2>
<ul>
<li>
<p>
<a href="GenerativeDatatype">GenerativeDatatype</a>
</p>
</li>
</ul>
</div>
<p>
<hr>
Last edited on 2010-03-02 15:11:39 by <span title="fenrir.cs.rit.edu"><a href="MatthewFluet">MatthewFluet</a></span>.
</body></html>
|