Version française
Home     About     Download     Resources     Contact us    
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: -- (:)
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
cleanup;
r

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:

	before
	try
		let fd = open fd
		try
			middle
		finally
			close fd
	finally
		after

> 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