Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: [Caml-list] Static exception analysis or alternative to using exceptions

0 views
Skip to first unread message

Dario Teixeira

unread,
May 26, 2010, 1:30:48 PM5/26/10
to Hans Ole Rafaelsen, caml...@yquem.inria.fr
Hi,

> What experience does people have to using alternatives to exceptions,
> such as option types or exception monads? Does use of third part
> libraries that still throws exceptions make such approaches hard to use?
> Performance wise it seems to be comparable to catching exceptions or
> matching for options, so I guess the difference be might a question of
> programming style?

Partly yes, though I would say that in Ocaml it is tempting to use
exceptions beyond what is reasonable, because they are so cheap and
convenient. As you noted, this can lead to trouble at runtime, which
is why some libraries discourage the "exceptional style", preferring
option types and forcing users to invoke functions suffixed by "_exc"
if they really want to use the exception-based version.

Personally, I think the litmus test hinges on whether the supposedly
exceptional situation is truly worthy of the name. If it's a common
occurrence, perhaps one should reconsider the use of an "exception".
Without meaning to start an holy war, let me just add that even on
the Stdlib there are functions (such as Map.S.find) that raise an
exception but which should perhaps return an option type.

Btw, you didn't mention it explicitly in your message, but I trust you
are familiar with "Catch me if you can"? [1]

Best regards,
Dario Teixeira

[1] http://dutherenverseauborddelatable.wordpress.com/downloads/exception-monads-for-ocaml/

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

Hans Ole Rafaelsen

unread,
May 26, 2010, 5:10:10 PM5/26/10
to Dario Teixeira, caml...@yquem.inria.fr
On Wed, May 26, 2010 at 7:30 PM, Dario Teixeira <dariot...@yahoo.com>wrote:

> Hi,
>
> > What experience does people have to using alternatives to exceptions,
> > such as option types or exception monads? Does use of third part
> > libraries that still throws exceptions make such approaches hard to use?
> > Performance wise it seems to be comparable to catching exceptions or
> > matching for options, so I guess the difference be might a question of
> > programming style?
>
> Partly yes, though I would say that in Ocaml it is tempting to use
> exceptions beyond what is reasonable, because they are so cheap and
> convenient. As you noted, this can lead to trouble at runtime, which
> is why some libraries discourage the "exceptional style", preferring
> option types and forcing users to invoke functions suffixed by "_exc"
> if they really want to use the exception-based version.
>
> Personally, I think the litmus test hinges on whether the supposedly
> exceptional situation is truly worthy of the name. If it's a common
> occurrence, perhaps one should reconsider the use of an "exception".
> Without meaning to start an holy war, let me just add that even on
> the Stdlib there are functions (such as Map.S.find) that raise an
> exception but which should perhaps return an option type.
>
> Btw, you didn't mention it explicitly in your message, but I trust you
> are familiar with "Catch me if you can"? [1]
>

I have just read about it, not tested it yet. Do you have any experience
using this library, especially together with other libraries that also
provides syntax extension?

> Thanks,

Hans Ole

Jacques Le Normand

unread,
May 26, 2010, 11:37:59 PM5/26/10
to Hans Ole Rafaelsen, caml...@yquem.inria.fr
Jane Street's Core seems to prefer options to exceptions

Florent Ouchet

unread,
May 27, 2010, 4:08:44 AM5/27/10
to caml...@yquem.inria.fr
Hello,

Same here, specially to avoid the Not_found exception.
The optional return values gives the oportunity to have a clear view of
what is being done if the result is not available.

- Florent

Jacques Le Normand a �crit :

> ------------------------------------------------------------------------


>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>


--
Florent Ouchet
PhD Student
CIS/VDS Team - TIMA Laboratory

Eray Ozkural

unread,
May 27, 2010, 4:50:47 AM5/27/10
to Florent Ouchet, caml...@yquem.inria.fr
On Thu, May 27, 2010 at 11:08 AM, Florent Ouchet <florent...@imag.fr> wrote:
> Hello,
>
> Same here, specially to avoid the Not_found exception.
> The optional return values gives the oportunity to have a clear view of what
> is being done if the result is not available.

That depends on the code, I think. In some cases the exception may
arise from deep in the code, and it would make sense not to bother
with a lot of type overhead for many levels of nesting and function
calling. But if all you are doing is checking the success of a
function, I suppose option types will be more efficient.

Best,

--
Eray Ozkural, PhD candidate. Comp. Sci. Dept., Bilkent University, Ankara
http://groups.yahoo.com/group/ai-philosophy
http://myspace.com/arizanesil http://myspace.com/malfunct

David Allsopp

unread,
May 27, 2010, 4:54:56 AM5/27/10
to Florent Ouchet, caml...@yquem.inria.fr
Florent Ouchet wrote:
> Same here, specially to avoid the Not_found exception.
> The optional return values gives the oportunity to have a clear view of
> what is being done if the result is not available.

Agreed - though [find] is one of the examples where you do need find and
find_exc - because often there are occasions where before calling
{Map,Set,Hashtbl}.find you already know that the key exists and so won't
fail at which point the 'a option boxing is a waste of time and space and
Not_found would be a truly exceptional situation so passes the previously
mentioned test.


David

Mark Shinwell

unread,
May 27, 2010, 5:11:22 AM5/27/10
to David Allsopp, caml...@yquem.inria.fr
On Thu, May 27, 2010 at 09:54:29AM +0100, David Allsopp wrote:
> Florent Ouchet wrote:
> > Same here, specially to avoid the Not_found exception.
> > The optional return values gives the oportunity to have a clear view of
> > what is being done if the result is not available.
>
> Agreed - though [find] is one of the examples where you do need find and
> find_exc - because often there are occasions where before calling
> {Map,Set,Hashtbl}.find you already know that the key exists and so won't
> fail at which point the 'a option boxing is a waste of time and space and
> Not_found would be a truly exceptional situation so passes the previously
> mentioned test.

I don't think I agree with this. I would argue that for the majority of
programs it is likely that the extra overhead is in fact negligible. In
the cases where it should be impossible to get the None return value, I
think that should probably be annotated as such in the code with "assert
false", which would seem to be more appropriate than a random Not_found
popping up at some much higher level.

In some cases it might be possible to refactor the code to just avoid the
situation entirely, for example by turning this:

if not (Map.mem my_map key) then
..a..
else
..b..
let data = Map.find_exn my_map key in
..c..

into this:

match Map.find my_map key with
| None -> ..a..
| Some data -> ..b.. ..c..

Whilst I agree that there are arguments relating to verbosity of the use
of option types, I think the strongest argument for keeping the *_exn
variants may actually be that they're just a lot more convenient for quick
hacks.

Mark

Daniel Bünzli

unread,
May 27, 2010, 5:12:26 AM5/27/10
to caml...@yquem.inria.fr
> Agreed - though [find] is one of the examples where you do need find and
> find_exc - because often there are occasions where before calling
> {Map,Set,Hashtbl}.find you already know that the key exists and so won't
> fail at which point the 'a option boxing is a waste of time and space and
> Not_found would be a truly exceptional situation so passes the previously
> mentioned test.

In that case what you want is an alternate function "really_find" that
doesn't raise Not_found but Invalid_argument if the key cannot be
found.

Best,

Daniel

David Rajchenbach-Teller

unread,
May 27, 2010, 5:15:27 AM5/27/10
to Florent Ouchet, caml...@yquem.inria.fr
Hi,
If you're interested, three of us on this mailing-list wrote a paper on the topic two few years ago [1].

Best regards,
David

[1] _Catch me if you can Looking for type-safe, hierarchical, lightweight, polymorphic and efficient error management in OCaml_, http://en.scientificcommons.org/52393896

David Allsopp

unread,
May 27, 2010, 5:20:10 AM5/27/10
to Daniel Bünzli, caml...@yquem.inria.fr
Daniel Bünzli wrote:
> > Agreed - though [find] is one of the examples where you do need find
> > and find_exc - because often there are occasions where before calling
> > {Map,Set,Hashtbl}.find you already know that the key exists and so
> > won't fail at which point the 'a option boxing is a waste of time and
> > space and Not_found would be a truly exceptional situation so passes
> > the previously mentioned test.
>
> In that case what you want is an alternate function "really_find" that
> doesn't raise Not_found but Invalid_argument if the key cannot be found.

Absolutely - but the point is that there is an obvious need to have the exception vs 'a option versions of the function. Appropriate naming of exceptions in the standard library is a well-rehearsed discussion :o)


David

David Allsopp

unread,
May 27, 2010, 5:30:15 AM5/27/10
to Mark Shinwell, David Allsopp, caml...@yquem.inria.fr
Mark Shinwell wrote:
> On Thu, May 27, 2010 at 09:54:29AM +0100, David Allsopp wrote:
> > Florent Ouchet wrote:
> > > Same here, specially to avoid the Not_found exception.
> > > The optional return values gives the oportunity to have a clear view
> > > of what is being done if the result is not available.
> >
> > Agreed - though [find] is one of the examples where you do need find
> > and find_exc - because often there are occasions where before calling
> > {Map,Set,Hashtbl}.find you already know that the key exists and so
> > won't fail at which point the 'a option boxing is a waste of time and
> > space and Not_found would be a truly exceptional situation so passes
> > the previously mentioned test.
>
> I don't think I agree with this. I would argue that for the majority of
> programs it is likely that the extra overhead is in fact negligible. In
> the cases where it should be impossible to get the None return value, I
> think that should probably be annotated as such in the code with "assert
> false", which would seem to be more appropriate than a random Not_found
> popping up at some much higher level.

assert false is just a way of renaming the exception and relies on the
rather dirty (but necessary) hack in the compiler that, as a special case,
assert false is not optimised out of a program compiled without debugging
checks.

<snip>

> Whilst I agree that there are arguments relating to verbosity of the use
> of option types, I think the strongest argument for keeping the *_exn
> variants may actually be that they're just a lot more convenient for quick
> hacks.

Unnecessary verbosity = unreadable IMHO, that's one of the reasons we use
clear, functional languages in the first place. That overhead also isn't
negligible as soon as you've got a Hashtbl/Set/Map which is queried a lot
(i.e. just about any form of data processing). Code where you know a priori
that the keys exist becomes unnecessarily peppered with pointless match
clauses (or calls like ExtLib's Option.get which... would raise an exception
if faced with None!). The interest to me is not that the overhead is
negligible, but that it can be trivially removed by using a *better*
function in that instance. Obviously, in the perfect world, your call to the
_exc version would in reality carry a proof that the key will be found (and
so no exception would be necessary). I simply don't see that the overarching
reason to have the _exc version of the function would be simply for hacking
a quick solution to a problem where you can't be bothered to handle the
Not_found case.


David

Alain Frisch

unread,
May 27, 2010, 5:34:44 AM5/27/10
to Hans Ole Rafaelsen, caml...@inria.fr
On 05/26/2010 06:15 PM, Hans Ole Rafaelsen wrote:
> What experience does people have to using alternatives to exceptions,
> such as option types or exception monads? Does use of third part
> libraries that still throws exceptions make such approaches hard to use?
> Performance wise it seems to be comparable to catching exceptions or
> matching for options, so I guess the difference be might a question of
> programming style?

Indeed, this is mostly a matter of taste and style.

My personal "Rule #1" to decide to use exceptions or not is that one:

Raising an exception is ok if you know where it will be caught
or which global effect it will have on the application.


This includes the following cases:

- (Short jumps) Using exceptions locally as shortcuts in loops or more
complex algorithms. In that case, the runtime exception is encapsulated
in a function or module, and should not cause any harm.

- (Long jumps) Using exceptions to report unexpected errors, to which
the application has little chance to react in a clever way except
displaying some error messages to the screen or to a log file. The catch
point is a global exception handler, even though the code raising the
exception (maybe in a general purpose library) might not know exactly
how the application will react to the exception. It is much better if
the exception describes the problems in terms that can be understood by
a human (Not_found, even with a stack trace, is not very helpful as an
error message).

Library function that perform some kind of lookup should return an
option type and let the caller raise a proper exception to report error
in a way that makes sense for the application. Similarly for other kind
of functions that can "fail": use a sum type (or polymorphic variants)
instead to describe the possible "errors". A variant of the function
that raises an exception is acceptable for cases where the caller really
expect the function to succeed (it can fail only because of bugs in the
application, not because of user or system errors). In that case,
Assert_failure, or a custom exception, is probably better than
Not_found. More generally, if exceptions are to be used, custom ones are
usually better than generic ones (Failure, Invalid_argument).

Another interesting use of exceptions comes from the fact that exn is an
extensible sum type. (Unfortunately, it is the only one in OCaml.) This
enables some kinds of loosely typed scenarios, like notification
messages to be dispatched across global objects in the application: the
list of possible messages is not fixed in advance, and each object can
simply use pattern matching to react on messages it is interested in.
But this is another story...

Alain

Florent Ouchet

unread,
May 27, 2010, 7:10:56 AM5/27/10
to Eray Ozkural, caml...@yquem.inria.fr

In VSYML [1], the exception Not_found was raised deep in the code in
some functions from List and in some redefined functions (such as
ocamlutils_find_assoc with a custom key comparer). This project can be
assimilable to a code compiler or a code interpreter where these
functions are called during the syntax tree conversion.

There is not "real" problem when the exception is caught at an higher
level but when the exception is not caught at the "deep-1" level, the
user will likely receive the wrong error message and this error will
likely be reported at the wrong position in the VHDL source file. That
was just disturbing and it required some "tact" to find the exact problem.

In version VSYML 1.7, I switched from exception to optional result and
the application is more stable. By using optional result, the required
pattern matching ensures the error handling at the deep-1 level.

[1] VSYML: VHDL Symbolic Simulator in OCaml
http://users-tima.imag.fr/vds/ouchet/vsyml.html

- Florent

Eray Ozkural a �crit :


> On Thu, May 27, 2010 at 11:08 AM, Florent Ouchet <florent...@imag.fr> wrote:
>
>> Hello,
>>
>> Same here, specially to avoid the Not_found exception.
>> The optional return values gives the oportunity to have a clear view of what
>> is being done if the result is not available.
>>
>
> That depends on the code, I think. In some cases the exception may
> arise from deep in the code, and it would make sense not to bother
> with a lot of type overhead for many levels of nesting and function
> calling. But if all you are doing is checking the success of a
> function, I suppose option types will be more efficient.
>
> Best,
>
>


--

Florent Ouchet
PhD Student
CIS/VDS Team - TIMA Laboratory

_______________________________________________

Hezekiah M. Carty

unread,
May 27, 2010, 9:57:37 AM5/27/10
to Jacques Le Normand, caml...@yquem.inria.fr
On Wed, May 26, 2010 at 11:37 PM, Jacques Le Normand
<rathe...@gmail.com> wrote:
> Jane Street's Core seems to prefer options to exceptions
>

Batteries also includes a number of Exceptionless modules (ex.
Array.Exceptionless) which wrap exception-raising functions to use
options instead.

Richard Jones

unread,
May 27, 2010, 1:01:30 PM5/27/10
to Hans Ole Rafaelsen, caml...@inria.fr
On Wed, May 26, 2010 at 06:15:05PM +0200, Hans Ole Rafaelsen wrote:
> What experience does people have to using alternatives to exceptions, such
> as option types or exception monads? Does use of third part libraries that
> still throws exceptions make such approaches hard to use? Performance wise
> it seems to be comparable to catching exceptions or matching for options, so
> I guess the difference be might a question of programming style?

Personally I've found that you should only throw those exceptions
which can be caught in a single place in the program. By this I mean
that an exception such as Not_found shouldn't be thrown, and instead
it would be better to use an option type (for stdlib functions which
throw Not_found, you have to be _very_ careful that the exception
cannot "escape").

However if the exception is, say, an I/O error reading a disk file,
these should be thrown, and caught somewhere central where you can
display an error message to the user (for GUI programs) or abort the
current transaction (for server programs). Recovering from such
exceptions properly is still tricky though. Since OCaml lacks
'finally', you either have to use a 'finally' impl from a library, or
modify your code to not need it (eg. turning calls to 'open_in' and
'open_out' into a kind of continuation-passing style). Or for small
programs, abort the program and don't deal with recovery at all.

All in all, this is not ideal for writing correct programs. Some sort
of exception analysis would be most welcome.

Rich.

--
Richard Jones
Red Hat

Dario Teixeira

unread,
May 27, 2010, 5:13:37 PM5/27/10
to Hans Ole Rafaelsen, Richard Jones, caml...@inria.fr
Hi,

> Personally I've found that you should only throw those exceptions
> which can be caught in a single place in the program.� By this I mean
> that an exception such as Not_found shouldn't be thrown, and instead
> it would be better to use an option type (for stdlib functions which
> throw Not_found, you have to be _very_ careful that the exception
> cannot "escape").

Yes, I agree. As an illustration, dictionary lookup functions such as
Map.find should return an option type, but use exceptions for truly
exceptional circumstances that no sane programmer should have to watch
for at every single invocation (say, "raise Dictionary_eaten_by_bears").

Cheers,
Dario Teixeira

Goswin von Brederlow

unread,
May 31, 2010, 10:36:29 AM5/31/10
to Richard Jones, caml...@inria.fr
Richard Jones <ri...@annexia.org> writes:

> On Wed, May 26, 2010 at 06:15:05PM +0200, Hans Ole Rafaelsen wrote:
>> What experience does people have to using alternatives to exceptions, such
>> as option types or exception monads? Does use of third part libraries that
>> still throws exceptions make such approaches hard to use? Performance wise
>> it seems to be comparable to catching exceptions or matching for options, so
>> I guess the difference be might a question of programming style?
>
> Personally I've found that you should only throw those exceptions
> which can be caught in a single place in the program. By this I mean
> that an exception such as Not_found shouldn't be thrown, and instead
> it would be better to use an option type (for stdlib functions which
> throw Not_found, you have to be _very_ careful that the exception
> cannot "escape").

Which needlessly complicates your code when it never happens.

Imho a good module should provide both an exception and option based
interface to fit the circumstances and programming style.

> However if the exception is, say, an I/O error reading a disk file,
> these should be thrown, and caught somewhere central where you can
> display an error message to the user (for GUI programs) or abort the
> current transaction (for server programs). Recovering from such
> exceptions properly is still tricky though. Since OCaml lacks
> 'finally', you either have to use a 'finally' impl from a library, or
> modify your code to not need it (eg. turning calls to 'open_in' and
> 'open_out' into a kind of continuation-passing style). Or for small
> programs, abort the program and don't deal with recovery at all.
>
> All in all, this is not ideal for writing correct programs. Some sort
> of exception analysis would be most welcome.

It would be nice if the possible exceptions of a function would be part
of the type. E.g.

let f1 () = raise Not_found
val f1 : unit -> 'a [ Not_found ]

let f2 () = try f1 () with Not_found -> ()
val f2 : unit -> unit

let f3 f = try f () with Not_found -> ()
val f3: (unit -> 'a [< Not_found | 'B ]) -> 'a [ 'B ]

and so on.


Someone would have to write a new type system for that though.

MfG
Goswin

Florent Ouchet

unread,
May 31, 2010, 11:00:42 AM5/31/10
to Goswin von Brederlow, caml...@inria.fr
Goswin von Brederlow a �crit :

> Imho a good module should provide both an exception and option based
> interface to fit the circumstances and programming style.
>
>
+1

> It would be nice if the possible exceptions of a function would be part
> of the type. E.g.
>
> let f1 () = raise Not_found
> val f1 : unit -> 'a [ Not_found ]
>
> let f2 () = try f1 () with Not_found -> ()
> val f2 : unit -> unit
>
> let f3 f = try f () with Not_found -> ()
> val f3: (unit -> 'a [< Not_found | 'B ]) -> 'a [ 'B ]
>
> and so on.
>
>
> Someone would have to write a new type system for that though.
>
>

ocamlexc gave such results, but this tool is now discontinued and not
compatible with latest compilers :(

--
Florent Ouchet
PhD Student
CIS/VDS Team - TIMA Laboratory

David Allsopp

unread,
May 31, 2010, 1:24:39 PM5/31/10
to Goswin von Brederlow, Richard Jones, caml...@inria.fr
Goswin von Brederlow wrote:
<snip>

> > However if the exception is, say, an I/O error reading a disk file,
> > these should be thrown, and caught somewhere central where you can
> > display an error message to the user (for GUI programs) or abort the
> > current transaction (for server programs). Recovering from such
> > exceptions properly is still tricky though. Since OCaml lacks
> > 'finally', you either have to use a 'finally' impl from a library, or
> > modify your code to not need it (eg. turning calls to 'open_in' and
> > 'open_out' into a kind of continuation-passing style). Or for small
> > programs, abort the program and don't deal with recovery at all.
> >
> > All in all, this is not ideal for writing correct programs. Some sort
> > of exception analysis would be most welcome.
>
> It would be nice if the possible exceptions of a function would be part of
> the type. E.g.
>
> let f1 () = raise Not_found
> val f1 : unit -> 'a [ Not_found ]
>
> let f2 () = try f1 () with Not_found -> () val f2 : unit -> unit
>
> let f3 f = try f () with Not_found -> () val f3: (unit -> 'a [< Not_found
> | 'B ]) -> 'a [ 'B ]
>
> and so on.
>
>
> Someone would have to write a new type system for that though.

Would it be more practical to have that analysis as part of the .annot file?
Presumably a patch which merged and updated the codebase of ocamlexc to
produce exception-annotations in that manner might have a chance of making
it into the OCaml compiler itself. I'm guessing that what you're getting at
is the ability to see from your code that an exception could escape at any
given point rather than trying to add Java-style "checked exceptions" to
OCaml?


David

Nicolas Pouillard

unread,
May 31, 2010, 3:30:53 PM5/31/10
to Goswin von Brederlow, Richard Jones, caml...@inria.fr
On Mon, 31 May 2010 16:36:22 +0200, Goswin von Brederlow <goswi...@web.de> wrote:
> Richard Jones <ri...@annexia.org> writes:
>
> > On Wed, May 26, 2010 at 06:15:05PM +0200, Hans Ole Rafaelsen wrote:
> >> What experience does people have to using alternatives to exceptions, such
> >> as option types or exception monads? Does use of third part libraries that
> >> still throws exceptions make such approaches hard to use? Performance wise
> >> it seems to be comparable to catching exceptions or matching for options, so
> >> I guess the difference be might a question of programming style?
> >
> > Personally I've found that you should only throw those exceptions
> > which can be caught in a single place in the program. By this I mean
> > that an exception such as Not_found shouldn't be thrown, and instead
> > it would be better to use an option type (for stdlib functions which
> > throw Not_found, you have to be _very_ careful that the exception
> > cannot "escape").
>
> Which needlessly complicates your code when it never happens.
>
> Imho a good module should provide both an exception and option based
> interface to fit the circumstances and programming style.

Since having all functions in all flavours can lead to hard to interface
bloat, one should consider tiny functions to switch from a style to another.
It tends to be easier to start from an option type in the case of Not_found
instead of the other way around for the following reason:

* The typechecker does not remind us to catch the exception.
* We need a custom handler per exception.
* We need to take a thunk to delay the computation.

let not_found_to_option f =
try Some (f ())
with Not_found -> None

On the contrary look at:

let from_option exn = function
| Some x -> x
| None -> raise exn

Example: from_option Not_found (List.find p xs)

Best regards,

--
Nicolas Pouillard
http://nicolaspouillard.fr

Christophe Raffalli

unread,
May 31, 2010, 3:36:25 PM5/31/10
to caml...@yquem.inria.fr

> It would be nice if the possible exceptions of a function would be part
> of the type. E.g.
>
> let f1 () = raise Not_found
> val f1 : unit -> 'a [ Not_found ]
>
> let f2 () = try f1 () with Not_found -> ()
> val f2 : unit -> unit
>
> let f3 f = try f () with Not_found -> ()
> val f3: (unit -> 'a [< Not_found | 'B ]) -> 'a [ 'B ]
>
> and so on.
>
This is what PML does ... and what is nice is that is does not even
require the exception to be garded ...

>
> Someone would have to write a new type system for that though.
>
Yes, but this require very little new technology : a function having one
type or two as return type is basically the same ...
and polymorphic variant are very well suited to be the default practice
for exception (as in your f3 example).

The only questions (I think) are
- complexity of the algorithm (I think it shoud be OK)
- readability of inferred types (one could hide exception types by
default ?)

Cheers,
Christophe

signature.asc

Török Edwin

unread,
May 31, 2010, 4:55:10 PM5/31/10
to caml...@yquem.inria.fr

pattern-match like exhaustive check that all cases are covered could be
useful.
try
..
with Not_found -> ...

error: exception catch clause is not exhaustive, exceptions not covered:
....

Maybe using a separate keyword, or a compile-time flag for this?

> given point rather than trying to add Java-style "checked exceptions" to
> OCaml?
>

I think there are 2 things to watch out when looking at Java and exceptions:
- if a function throws too many exceptions, you sometimes see things
like "throws Exceptions", or "catch (Exception e) { // ignore }" in Java
code, which are completely useless, and might even lead to bugs
(silently ignoring all exceptions)
- throwing an exception when a lookup doesn't find something is not
always the best. Look at Java's class loader which throws an exception
when a class is not found (pretty common when loading plugins) instead
of returning null.

I think that lookup functions should come in 2 flavours:
- one that doesn't use exceptions (uses option types), for example
'find'. The key you are looking for may or may not be there
- one that uses exceptions, for example 'get'. You know that the key is
there (or should be there), and you want the value. If the key isn't
there its probably a bug, or a very rare condition so the exception is
good here. I think the exception variant could even be generated
automatically as a wrapper to the option variant (not viceversa)

Best regards,
--Edwin

Lukasz Stafiniak

unread,
May 31, 2010, 4:58:51 PM5/31/10
to Nicolas Pouillard, caml...@inria.fr
On Mon, May 31, 2010 at 9:30 PM, Nicolas Pouillard
<nicolas....@gmail.com> wrote:
>
> Since having all functions in all flavours can lead to hard to interface
> bloat, one should consider tiny functions to switch from a style to another.
> It tends to be easier to start from an option type in the case of Not_found
> instead of the other way around for the following reason:
>
> �* The typechecker does not remind us to catch the exception.
> �* We need a custom handler per exception.
> �* We need to take a thunk to delay the computation.
>
> �let not_found_to_option f =
> � �try Some (f ())
> � �with Not_found -> None
>
> On the contrary look at:
>
> �let from_option exn = function
> � �| Some x -> x
> � �| None -> raise exn
>
> �Example: from_option Not_found (List.find p xs)
>

I use a syntax extension that catches "Not_found" and raises a failure
instead, with the source location of the "real" offending call. I do
this mostly because OUnit catches exceptions so backtraces are of no
use. When I use the unmodified calls, I always handle Not_found right
away, close to call point -- either by directly catching it, or by
using a higher-order function, like an iterator that expects Not_found
instead of None from the callee. Anyway, I vote for "option"ising all
of the standard library and providing the function "unsome" raising a
string with source code location of its call.

Peter Ronnquist

unread,
Jun 1, 2010, 3:08:45 PM6/1/10
to caml...@inria.fr

Richard Jones wrote:
"... All in all, this is not ideal for writing correct programs. Some sort

of exception analysis would be most welcome."

Doesn't the "catch me if you can" library provide this?

Among the listed features are:
* case coverage (i.e. the compiler can tell you if you forgot a case or sometimes if you wrote useless ones)

Isn't it so that the "catch me if you can" library solves most (all?) problems related to error handling through exceptions in ocaml?
(The "Batteries included" project has listed it as a possible inclusion
for future versions (http://www.cocan.org/osr/batteriesincluded)

Regards
Peter R

Goswin von Brederlow

unread,
Jun 8, 2010, 5:16:31 AM6/8/10
to David Allsopp, caml...@inria.fr, Richard Jones
"David Allsopp" <dra-...@metastack.com> writes:

It want it to fail to compile if the interface specifies one set of
exception and the code produces another that is incompatible. The
following should not compile:

module M : sig
val f : int -> int []
end = struct
let h = Hashtbl.create 0
let f x = Hashtbl.find x
end

Since Hashtbl.find can throw Not_found and the function does not catch
that the function still can throw Not_found. This violates the
declaration in the signature that says it never throws an exception.

This goes beyond just annotating what exception can be thrown. It should
do a real validation.

MfG
Goswin

0 new messages