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 (11:42)
From: tab@s...
Subject: Re: [Caml-list] Ocaml compiler features
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

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.

> 	try 
> 		before
> 		open f 
> 		middle
> 		close f
> 		after
> 	with _ -> close f
> then you have all sorts of problems if a different exception
> is thrown in the before or after parts. Using type information
> to distinguish the kind of exception is clearly a hack:
> what if you're opening two files?

The thing is you don't do this with a flat block. If you need to unwind
a complex state you do:

		let fd = open fd
			close fd

> Yes, but you can do what many people do: map the exceptions into
> variants like:
> 	let hfind x y  = 
> 		try Some(Hashtbl.find x y) 
> 		with Not_found -> None 

I'm not arguing against this method. You do it the way you want,
but when you use exception, having a finally is very handy for a lots of
case. Nothing more, nothing less.

> 	let fopen f lock = try Some (open f) with Error -> None in
> 	let lck = mutex () in lock mutex;
> 	let f = fopen name lck in
> 	match f with
> 	| Some file -> ... close, release lck
> 	| None -> release lck
> WOOPS! Again we had to repeat the cleanup code.
> Releasing the mutex AFTER the whole code works, but
> if we want separate control flows for the two cases
> we have to test the variant again:
> 	begin match f with .. end; release lck;
> 	match f with .. (* fork again  *)
> So actually, you could use a 'finally' here too: 

seems that you *finally* understand it ;)

Vincent Hanquez