<div dir="ltr"><br><br><div class="gmail_quote">On Mon, Dec 7, 2009 at 8:40 AM, Alexander Dunlap <span dir="ltr">&lt;<a href="mailto:alexander.dunlap@gmail.com">alexander.dunlap@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div><div></div><div class="h5">On Sat, Dec 5, 2009 at 3:00 PM, Michael Snoyman &lt;<a href="mailto:michael@snoyman.com">michael@snoyman.com</a>&gt; wrote:<br>
&gt;<br>
&gt;<br>
&gt; On Sun, Dec 6, 2009 at 12:55 AM, Henning Thielemann<br>
&gt; &lt;<a href="mailto:lemming@henning-thielemann.de">lemming@henning-thielemann.de</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; On Sun, 6 Dec 2009, Michael Snoyman wrote:<br>
&gt;&gt;<br>
&gt;&gt;&gt; I think there are plenty of examples like web servers. A text editor with<br>
&gt;&gt;&gt; plugins? I<br>
&gt;&gt;&gt; don&#39;t want to lose three hours worth of work just because some plugin<br>
&gt;&gt;&gt; wasn&#39;t written<br>
&gt;&gt;&gt; correctly. For many classes of programs, the distinction between error<br>
&gt;&gt;&gt; and exception is<br>
&gt;&gt;&gt; not only blurred, it&#39;s fully irrelevant. Harping on people every time<br>
&gt;&gt;&gt; they use error in<br>
&gt;&gt;&gt; the &quot;wrong&quot; sense seems unhelpful.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Hope my commenting on this subject doesn&#39;t become my own form of<br>
&gt;&gt;&gt; *pedantry*.<br>
&gt;&gt;<br>
&gt;&gt; In an earlier thread I have explained that one can consider a software<br>
&gt;&gt; architecture as divided into levels. What is an error in one level (text<br>
&gt;&gt; editor plugin, web server thread, operating system process) is an exception<br>
&gt;&gt; in the next higher level (text editor, web server, shell respectively). This<br>
&gt;&gt; doesn&#39;t reduce the importance to distinguish between errors and exceptions<br>
&gt;&gt; within one level. All approaches so far that I have seen in Haskell just mix<br>
&gt;&gt; exceptions and errors in an arbitrary way.<br>
&gt;<br>
&gt; I think we can all appreciate why it would be a bad thing is we treat<br>
&gt; exceptions as errors. For example, I don&#39;t want my program to crash on a<br>
&gt; file not found.<br>
&gt;<br>
&gt; On the other hand, what&#39;s so bad about treating errors as exceptions? If<br>
&gt; instead of the program crashing on an array-out-of-bound or pattern-match it<br>
&gt; throws an exception which can be caught, so what?<br>
&gt;<br>
&gt; Michael<br>
&gt;<br>
<br>
</div></div>I think the key is in the difference between the user/client and<br>
programmer/developer. As Henning has been saying, these roles change<br>
as you go through the different levels of the program, but I see the<br>
difference between an error and an exception as this: when a problem<br>
is relevant to the user/client, it&#39;s an exception; when it is<br>
irrelevant to the user/client, it&#39;s an error. Suppose you were using<br>
some sort of exception framework and you got an error from a piece of<br>
library code (not the head function) saying that &quot;head&quot; had failed<br>
somewhere. This is absolutely meaningless to a client. It just means<br>
there&#39;s a problem in the library code; it doesn&#39;t mean anything is<br>
amiss in the client&#39;s space. The client basically has to throw the<br>
function out, whether by gracefully aborting the program, disabling<br>
the plugin, etc. Contrast this with an exception, such as &quot;index not<br>
in map.&quot; This is entirely relevant to the client. All of the code<br>
knows exactly what is going on; it&#39;s just that the index isn&#39;t in the<br>
map. The client can recover from this by, say, substituting a default<br>
value, adding the index to the map, etc. Now, suppose the client knew<br>
a priori that the index was *supposed* to be in the map. Now this<br>
becomes an *error* to the *client* of the client, since there is a bug<br>
in the first client&#39;s code.<br>
<br>
I guess my point is that if I have a function, say, sort :: Ord a =&gt;<br>
[a] -&gt; [a], and sort calls head somewhere in it, there&#39;s no point<br>
having &quot;sort&quot; throw an exception for &quot;Prelude.head: []&quot; since that<br>
means nothing to the client. It would make more sense to have an<br>
InternalError type that just says &quot;OK, sorry client, I screwed up,<br>
just clean things up as best you can&quot;. If really were something that<br>
the client could have responded to, sort should have caught the head<br>
error inside the function definition and rethrown a different<br>
exception; say, SortEmptyListError if your sort function didn&#39;t work<br>
on empty lists (contrived example, sorry).<br>
<br>
Alex<br>
</blockquote></div>The WrapFailure typeclass in the the failure package makes this kind of library design fairly straightforward. I think you&#39;re making an argument for treating errors and exceptions the same way.<br>
<br>Michael<br></div>