Version française
Home     About     Download     Resources     Contact us    
Browse thread
Today's inflamatory opinion: exceptions are bad
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Chris King <colanderman@g...>
Subject: Re: [Caml-list] Today's inflamatory opinion: exceptions are bad
On 12/9/06, Brian Hurt <bhurt@spnz.org> wrote:
> The second reason is that match ... with doesn't break tail recursion,
> while try ... with does.  This code is not tail recursive:
>
> let rec echo_file channel =
>        try
>                begin
>                        let line = input_line channel in
>                        print_string (line ^ "\n");
>                        echo_file channel
>                end
>        with
>                | End_of_file -> ()
> ;;

I'm a big fan of Martin Jambon's "let try" syntax extension [1].  With
it the above construct can be written as:

let rec echo_file channel =
    let try line = input_line channel in
    print_string (line ^ "\n");
    echo_file channel
    with End_of_file -> ()

and would be tail-recursive.  More often than not this is how I want
to write my exception handlers.


> My point here is this: Ocaml is not Java (a fact we should all be
> gratefull for, IMHO).  Simply because Java and C++ do something, doesn't
> mean that it's a good thing to do.

One thing Java (sort of) gets right is keeping track of which
exceptions a function can throw, making it easy to ensure that some
deeply nested piece of code won't cause the entire application to die
from some obscure exception.  I'd love to see a similar feature in
O'Caml, whereby the exceptions which a function can raise are part of
its type and are inferred and checked by the compiler.  For example:

val List.assoc: 'a -> ('a * 'b) list -> 'b raises Not_found
val List.iter: ('a -> unit raises 'b) -> 'a list -> unit raises 'b

This would make it easy to spot which exceptions go uncaught in the
main function of a program (perhaps the compiler could even emit a
warning in this case), as well as allowing the programmer to ensure
that certain pieces of code won't raise arbitrary exceptions.  As an
example of the latter, a stricter version of List.iter could have the
type:

val iter_until: ('a -> unit raises Exit) -> 'a list -> unit

Of course, this system would probably require that type exn be
eschewed for something closer to a polymorphic variant so that typing
in 'catch' statements will work correctly.  Then types such as

val catch_failures: ('a -> 'b raises [Failure of string | 'c]) -> 'a
-> 'b raises 'c

would be possible.

- Chris

[1] http://martin.jambon.free.fr/extend-ocaml-syntax.html#lettry