From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=AWL autolearn=disabled version=3.1.3 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id 19541BC6C for ; Mon, 28 Jan 2008 21:54:38 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Aq4HALjPnUfUnw6GgGdsb2JhbACCNo1zAQEJCiIHmxM X-IronPort-AV: E=Sophos;i="4.25,262,1199660400"; d="scan'208";a="7348174" Received: from pih-relay08.plus.net ([212.159.14.134]) by mail1-smtp-roc.national.inria.fr with ESMTP; 28 Jan 2008 21:54:38 +0100 Received: from [80.229.56.224] (helo=beast.local) by pih-relay08.plus.net with esmtp (Exim) id 1JJb00-0005Zc-RV for caml-list@yquem.inria.fr; Mon, 28 Jan 2008 20:54:37 +0000 From: Jon Harrop Organization: Flying Frog Consultancy Ltd. To: caml-list@yquem.inria.fr Subject: Re: [Caml-list] [OSR] OCaml Standard Recommandation Process Date: Mon, 28 Jan 2008 20:49:08 +0000 User-Agent: KMail/1.9.7 References: <200801281204.00689.jon@ffconsultancy.com> <200801281525.12651.jon@ffconsultancy.com> <20080128.170610.265034237530039453.Christophe.Troestler+ocaml@umh.ac.be> In-Reply-To: <20080128.170610.265034237530039453.Christophe.Troestler+ocaml@umh.ac.be> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200801282049.08477.jon@ffconsultancy.com> X-Plusnet-Relay: 6fd30eaef3a9ea93cf83f890f7452130 X-Spam: no; 0.00; ocaml:01 christophe:01 troestler:01 translated:01 combinators:01 val:01 val:01 combinators:01 stdlib:01 complained:01 frog:98 wrote:01 wrote:01 syntactic:01 clearer:01 On Monday 28 January 2008 16:06:10 Christophe TROESTLER wrote: > On Mon, 28 Jan 2008 15:25:12 +0000, Jon Harrop wrote: > > So you write a "use" binding: > > > > let read_first_line file = > > use ch = open_in file in > > input_line ch > > > > and it gets translated into: > > > > let read_first_line file = > > let ch = open_in file in > > try input_line ch finally > > ch#dispose > > > > where the "dispose" method that was automatically inserted at the end of > > the scope of the "use" binding calls "close_in" in this case to > > deallocate the external resource (a file handle in this case but it could > > be anything with a dispose method). > > What is wrong with > > let read_first_line file = > with_open_in file begin fun ch -> > input_line ch > end Sure. Here's the complete version using combinators as a workaround: # let try_finally x f g = try let f_x = f x in g x; f_x with e -> (try g x with _ -> ()); raise e;; val try_finally : 'a -> ('a -> 'b) -> ('a -> unit) -> 'b = # let with_open_in file k = try_finally (open_in file) k close_in;; val with_open_in : string -> (in_channel -> 'a) -> 'a = # let read_first_line file = with_open_in file begin fun ch -> input_line ch end;; val read_first_line : string -> string = This is almost exactly what I currently do. The "use" binding is syntactic sugar to make it shorter, clearer, more generic and scale better. I'd be more than happy to have anything at all added to improve this though. Combinators in the stdlib are certainly better than nothing and this is one of the most complained about noob problems (and lack of functions to read files)... -- Dr Jon D Harrop, Flying Frog Consultancy Ltd. http://www.ffconsultancy.com/products/?e