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=1.5 required=5.0 tests=AWL,DNS_FROM_RFC_POST, SPF_NEUTRAL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr 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 C0D47BB84 for ; Wed, 10 Dec 2008 23:58:21 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ag8BAL/YP0nRVdsVkGdsb2JhbACDHI9wPgEBAQEJCQwHEQOjaIEEjDwBAwEDgwM X-IronPort-AV: E=Sophos;i="4.33,749,1220220000"; d="scan'208";a="21092117" Received: from mail-ew0-f21.google.com ([209.85.219.21]) by mail1-smtp-roc.national.inria.fr with ESMTP; 10 Dec 2008 23:58:21 +0100 Received: by ewy14 with SMTP id 14so1047223ewy.3 for ; Wed, 10 Dec 2008 14:58:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to :subject:cc:in-reply-to:mime-version:content-type :content-transfer-encoding:content-disposition:references; bh=2xqQvO7b1BUy0KdeqyCmujJFOkWkNLuyVM+eV8vCAtM=; b=kMeZZmK3L60lby6av9N4PjqCVDwplgaS78n+1/rc8MB8MU2FXfIyqmdoyQwsPhNJkO OJn67+58ySfLCAH1+bKGln/2Srfs/qTa9gT5kBL8XWgAD8tDys/QdIXNvuuv2qH3y6eQ 1hjXaSfZKbhpx1mlt8ynvGyIUBpiVN2zzR5NY= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:cc:in-reply-to:mime-version :content-type:content-transfer-encoding:content-disposition :references; b=TlAPbQFV/9zq/CJn4L66XrtZMJCwuh9TMewgmd20s+gycZCgBDdJjNxu0rM4m4RjQH 7lCM/ySQG5HlvK411Vb1Op0xGikSEKj+Nxj0rookOE6n1DhThQENHmK+x1wgIaoQqALa rtOw8226uwl/CSlJ+idExBrtP18IMhOZD+/KQ= Received: by 10.210.24.12 with SMTP id 12mr159809ebx.19.1228949900723; Wed, 10 Dec 2008 14:58:20 -0800 (PST) Received: by 10.210.56.14 with HTTP; Wed, 10 Dec 2008 14:58:20 -0800 (PST) Message-ID: <527cf6bc0812101458l33b5a5cdkd60d13c369f0b449@mail.gmail.com> Date: Wed, 10 Dec 2008 23:58:20 +0100 From: "blue storm" To: "Conglun Yao" Subject: Re: [Caml-list] How to handle try .... finally properly? Cc: caml-list@yquem.inria.fr In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: X-Spam: no; 0.00; ocaml:01 camlp:01 camlp:01 ocaml:01 ad-hoc:01 haskell:01 storm:98 .....:98 invoke:01 polymorphic:01 ideally:01 partial:01 caml-list:01 caml-list:01 functions:01 > I'm thinking about how to handle try .... finally in ocaml, and found > one of camlp4 implementations from > http://bluestorm.info/camlp4/dev/try/pa_tryfinally.ml.html As you probably noticed, the website is down right now. I'll see that the files are reachable again as soon as possible (in the meantime, if you want specific files, mail me and i'll send them). I should also warn you that the files under the "dev/" prefix are "in development", and not supposed to be stable or free of bugs. > Example code adopted from Gabriel Scherer's pa_tryfinally The example code actually comes from a mailing-list discussion : http://caml.inria.fr/pub/ml-archives/caml-list/2007/01/31db0fd9b7e158f5679991560cb8f876.en.html > At the first glance, it answered my question. However, it solved the > problem partially, only working on functions with one argument. > > If we feed the * transform * a function with more than one argument, > (it is possible because of curring) > > transform (fun x y -> .... some logic staff .... ) x y > > will invoke the * after () * before the ((fun x y -> .....) x) y is > really executed. In that particular case, using "transform f x" to send a function and not a value would be plain wrong : the whole point of transform is "do the dirty things" inside the push/pop of the OpenGL matrix. If you push/pop when building your function, and then apply it later without restoring the matrix at the application time, you'll get uncorrect behavior, and this is not a try/finally-specific issue. > Ideally, * transform * function is specified as allowing a function f > with only one parameter. But it seems impossible in OCaml, > as f : 'a -> 'b doesn't means f can and only accept one argument. ( 'b > could be 'c -> 'd ) If we could constraint 'b as a non-function type, > it can solve the problem. This particular transform function is imperative in nature : the idea is to do side effects at the right moment. You could probably enforce the transformed function to return an unit type without that much loss of generality : let transform (f : 'a -> unit) x = ... That way, you can only transform ('a -> unit) functions, wich is a bit limited (though you could use side-effects to send back values through a reference for example) but should fit the intended use of the function well. In general, there is no solution to your problem. And I'm not even sure there is a problem, as you could wish to protect the partial evaluation of a function from raising exceptions : in some case, the behaviour you find problematic will actually be the expected and right thing to do. If you want your function to be polymorphic, you have to accept it could send anything back. If you want specialized "transform" functions for curryfied two-arguments functions or more, you could write ad-hoc functions for the 3, 4 or 5 parameters case. It sounds ugly but is a practical solution, in the spirit of what the Haskellers have done with their "zip, zip3, zip4, zip5" list functions ( http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html#17 ).