From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Delivered-To: caml-list@yquem.inria.fr Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 103F1BC48 for ; Wed, 9 Mar 2005 08:29:37 +0100 (CET) Received: from first.in-berlin.de (dialin-145-254-065-041.arcor-ip.net [145.254.65.41]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id j297TXHC032375 for ; Wed, 9 Mar 2005 08:29:35 +0100 Received: by first.in-berlin.de (Postfix, from userid 501) id CB1CFB56DE; Tue, 8 Mar 2005 23:19:29 +0100 (CET) Date: Tue, 8 Mar 2005 23:19:29 +0100 From: Oliver Bandel To: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Re: exception safety / RAII ? Message-ID: <20050308221929.GE1877@first.in-berlin.de> References: <293072a520e3724a0497e6456a8675be@mac.com> <200503071729.20117.jon@jdh30.plus.com> <877e9a1705030710476502ad31@mail.gmail.com> <200503080110.21839.jon@jdh30.plus.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200503080110.21839.jon@jdh30.plus.com> User-Agent: Mutt/1.5.6i X-Miltered: at concorde with ID 422EA5DD.002 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; oliver:01 bandel:01 oliver:01 in-berlin:01 caml-list:01 ocaml:01 o'caml:01 ocaml:01 incorrectly:01 deallocated:01 allocating:01 unix-module:01 buffered:01 reuse:01 pointers:01 X-Spam-Checker-Version: SpamAssassin 3.0.2 (2004-11-16) on yquem.inria.fr X-Spam-Status: No, score=0.3 required=5.0 tests=DATE_IN_PAST_06_12, FORGED_RCVD_HELO autolearn=disabled version=3.0.2 X-Spam-Level: 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 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 must be closed with 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