Version française
Home     About     Download     Resources     Contact us    
Browse thread
exception safety / RAII ?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Oliver Bandel <oliver@f...>
Subject: Re: [Caml-list] Re: exception safety / RAII ?
On Tue, Mar 08, 2005 at 01:10:21AM +0000, Jon Harrop wrote:
> On Monday 07 March 2005 18:47, Michael Walter wrote:
> > On Mon, 7 Mar 2005 17:29:19 +0000, Jon Harrop <jon@jdh30.plus.com> wrote:
> > > Would you mind elaborating a little on what you do desire, i.e. what does
> > > "using" do in C#, when would you use it and how does this relate to
> > > OCaml?
> >
> > Sure. I hope the following answers all three questions at once:
> >
> > let using resource thunk =
> >   try
> >     let
> >       result = thunk resource
> >     in
> >       dispose resource;
> >       result
> >   with
> >    any_exception ->
> >      dispose resource;
> >      raise any_exception
> >
> > My O'Caml is not very fluent, possible "dispose resource" should read
> > "resource # dispose".
> 
> Either is clear enough.
> 
> > Basically, the idea is to deterministically 
> > clean up resources, as early as possible (yes, "but it's not as early
> > as possible" is besides the point :-). In my experience this
> > simplifies resource management and reasoning about it.
> 
> Yes, so you can use your code to do this in OCaml. My concerns with such code 
> basically revolve around the possibility of incorrectly deallocating an 
> external resource and then using it again. This is not possible if you rely 
> on the GC but, as you say, the problem is then the lack of guarantees about 
> when resources have been deallocated by what point in the code.

Allocating ressources (here: "variables" or name-content-bindings)
is not a problem in  functional programming.

Such problems occur when using imperative style.

When using I/O then you work on imperative system's stuff,
like filehandles or simething, when e.g. using Unix-module.
Then you have to be careful, what you are doing.

But even when you use the buffered I/O then it is
linked to system ressources, which are imperative in nature.

This means: do not rely on the GC then!
Free ressources as soon as possible!

If you reuse a "variable" again in a functional
language then this does not yield to problems like
dangling pointers in C.

But nevertheless for example opening a directory to read it's contents
in a recursive function, that traverses a very long path with many subdirectories
(and maybe opening filhandles to all files in a directory)
may cause to problems.... even if the GC and the memory does not say
something abot it, the system may say, that there are no more filedescriptors
available...

Relying on the GC doe not help you to prevent problrms here.

Testing on directories with only a handful of files, nothing
goes wrong... but then used the software in "realworld",
it crashes... which in C means: writing coredump,
and in OCaml (if no internal bug yields to C-like bhaviour ;-))
menas an uncatched exception.


> 
> Perhaps explicitly asking the GC to deallocate all such resources is a better 
> solution? Depending on the circumstances, this could give a big performance 
> hit though...

Best solution, when regarding the filehandle-excample is:
open only if necessary and as late as possible
 (maybe think again about your algorithm in use)
and close as far as possible.

All, what you have to do in C or *ANY* other language
to write good code also applies to OCaml.

It may be a good style of programming to wrap every
imperative stuff (like file I/O) in an environment
that automatically allocates/deallocates the resources.

Something like Postscript's 
gsave/grestore
or that a tag like <mytag> must be closed with </mytag>
in XML-like code...
...so it also makes sense to do I/O only in an
environment of something like

open_ressource()
   (do_something()) 
close_ressource()


Writing wrappers seems not to be a big problem in a functional
language.

But maybe this Could be part oc OCaml++ or something like that ;-)


Maybe Haskell's I/O seems to be like that, but I'm not
such a Haskell expert and didn't explore Hashell's
I/O in detail.... (because I switched to OCaml before ;-))


Ciao,
   Oliver