Version française
Home     About     Download     Resources     Contact us    
Browse thread
How to handle try .... finally properly?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: blue storm <bluestorm.dylc@g...>
Subject: Re: [Caml-list] How to handle try .... finally properly?
> 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
).