English version
Accueil     À propos     Téléchargement     Ressources     Contactez-nous    

Ce site est rarement mis à jour. Pour les informations les plus récentes, rendez-vous sur le nouveau site OCaml à l'adresse ocaml.org.

Browse thread
Ocaml compiler features
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2007-01-17 (12:53)
From: Olivier Andrieu <oandrieu@n...>
Subject: Re: [Caml-list] Ocaml compiler features
On 1/17/07, Vincent Hanquez <tab@snarc.org> wrote:
> On Wed, Jan 17, 2007 at 02:28:47PM +1100, skaller wrote:
> > That is a reasonable argument to examine: but I'm not sure
> > finally is actually all that useful. If you're thinking of:
> >
> >       try maybe_throw X; do something
> >       finally -> cleanup done
> >
> > then it can be coded in Ocaml like:
> >
> >       begin try maybe_throw X; do something; cleanup
> >       with x -> cleanup; throw x end
> It would be more convincing if you hadn't made the trivial mistake to
> put the first cleanup function in the try.
> if for a really weird reason cleanup raises an exception, cleanup is done twice.
> the correct OCaml code is:
> let r = try maybe_throw X; do something; with exn -> cleanup; raise exn in
> cleanup;
> r

that's not clear-cut ; it depends on the cleanup function. For
instance, concerning I/O channels in the standard library, you have
close_out and close_out_noerr. They do not have the same behavior, and
you should rather use the _no_err one in the with exn part.

> the point is not it's hard to do, it's annoything to duplicate here and
> there, and doing the inline code lose the higher level view we can have
> with a syntaxic sugar like try-finally.

Just use a higher-order function: it won't duplicate code, it's
high-level and it doesn't require any syntactic sugar.

let with_file_out fname f =
  let oc = open_out fname in
  try let r = f oc in close_out oc ; r
  with exn -> close_out_noerr oc ; raise exn

let with_mat m f =
  GlMat.push () ;
  let r =
    try GlMat.mult m ; f ()
    with exn -> GlMat.pop () ; raise exn in
  GlMat.pop () ;