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=none autolearn=disabled version=3.1.3 Received: from discorde.inria.fr (discorde.inria.fr [192.93.2.38]) by yquem.inria.fr (Postfix) with ESMTP id E2058BC69 for ; Sun, 20 May 2007 20:30:52 +0200 (CEST) Received: from smtp3-g19.free.fr (smtp3-g19.free.fr [212.27.42.29]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id l4KIUqlI001238 for ; Sun, 20 May 2007 20:30:52 +0200 Received: from [192.168.0.1] (rke75-3-82-229-183-156.fbx.proxad.net [82.229.183.156]) by smtp3-g19.free.fr (Postfix) with ESMTP id E2E44603FF; Sun, 20 May 2007 20:30:51 +0200 (CEST) Message-ID: <4650A1EA.3050302@inria.fr> Date: Sun, 20 May 2007 21:30:50 +0200 From: Alain Frisch User-Agent: Thunderbird 2.0.0.0 (X11/20070326) MIME-Version: 1.0 To: Jon Harrop Cc: caml-list@yquem.inria.fr Subject: Re: [Caml-list] try .. finally .. References: <200705201842.59978.jon@ffconsultancy.com> In-Reply-To: <200705201842.59978.jon@ffconsultancy.com> X-Enigmail-Version: 0.95.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Miltered: at discorde with ID 465093DC.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; frisch:01 frisch:01 syntax:01 ocaml:01 expr:01 node:01 syntax:01 expr:01 exn:01 exn:01 ocaml:01 abstractions:01 camlp:01 wrote:01 exception:01 Jon Harrop wrote: > (* The function that returns unique identifiers *) > let new_id = > let counter = ref 0 in > fun () -> > incr counter; > "__finally" ^ string_of_int !counter > > (* The function that converts our syntax into a single OCaml expression, > i.e. an "expr" node of the syntax tree *) > let expand loc e1 e2 = > let id = new_id () in > let id_patt = <:patt< $lid:id$ >> in > let id_expr = <:expr< $lid:id$ >> in > <:expr< > let $id_patt$ = > try do { $e1$; None } > with [ exn -> Some exn ] in > do { $e2$; > match $id_expr$ with > [ None -> () > | Some exn -> raise exn ] } > >> Note that this implementation breaks tail positions of e2 (when no exception is raised in e1, one might want to preserve tail-calls in e2 -- or not)... > let unwind_protect f g = > let fin = ref false in > try > let x = f () in > fin := true; > g(); > x > with exn when !fin -> > g(); > raise exn and this one too, and you want (not !fin) instead of !fin. Why not: let unwind_protect f g = match (try f (); None with exn -> Some exn) with | None -> g () | Some exn -> g (); raise exn ? In the original version, I believe one could always use the same identifier, without any extra conflicts. In the second version, you also need to reserve one identifier (unwind_protect); of course, you can inline its definition. > Is this a general observation about macros? If you mean that regular OCaml abstractions are better behaved w.r.t. to the binding of identifiers than Camlp4 macros, I'd say the answer is yes. -- Alain