Version franÁaise
Home ††† About ††† Download ††† Resources ††† Contact us †††
Browse thread
How to add () to function parameters
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Till Varoquaux <till@p...>
Subject: Re: [Caml-list] How to add () to function parameters
Well I can basically see two solutions (plus countless complications
that I won't go into.)

We want to define a function

val cps3: f:('a -> 'b -> 'c -> 'd) -> ('d -> 'e) -> 'a -> 'b -> 'c -> 'e =

that takes a three argument function a returns the same function in CPS style.

The functional unparsing/danvy way [1]:

> let (++) f g = fun x -> f (g x)
> let i k f arg = k (f arg)
> let cps ty ~f k = ty k f
> let cps3 ~f = cps (i++i++i) ~f

brute force style:

> let e acc ~f cont = acc cont f
> let i = fun acc g -> g (fun cont v arg -> acc cont (v arg))
> let cps = fun z ->
>   let acc = (fun cont x -> cont x) in
>   z acc
> let cps3 ~f = cps i i i e ~f

The first style is an acquired taste quite the same way that monad
are. With some getting use to and abstracting your types in a sensible
way you can enclose things quite nicely and define elegant
printf/scanf kind of functions.

I strongly discourage you to use the second style. It is a very
reworked mlton.fold [2] style solution. mlton's fold is a lot more
esoteric and leads to types that I have never been able to abstract
properly.

Till

[1] http://www.brics.dk/RS/98/12/
[2] http://mlton.org/Fold

On Wed, Oct 14, 2009 at 6:44 AM, Till Crueger <Till.Crueger@gmx.net> wrote:
> Hi,
>
> I am looking for a way to add a unit parameter to a function that takes an
> arbitrary number of parameters. If the number of parameters is known this is
> fairly easy and I can just do:
>
> let lift1 f a =
>   fun () ->
>      f a;;
>
> let lift2 f a b =
>   fun () ->
>     f a b;;
>
> (all these create one closure per lifting)
> etc...
>
> However it is a bit of a hassle to have to code each of these lifts... So
> what I am looking for is a way to extend this pattern to all numbers. So far
> I got to the point that I can do the following:
>
> let lift_once f a =
>   fun () ->
>      f a;;
>
> let lift_more f a =
>   fun () ->
>      f () a;;
>
> So for a function f taking two parameters a and b I can do
>
> lift_more (lift_once f a) b
> (two closures created)
>
> and for a function taking the parameters a, b and c I can do
>
> lift_more (lift_more (lift_once f a) b) c
> (three closures created)
>
> to get the lifted functions.
>
> However this solution gets quite ugly with all the parentheses. Also there
> are a lot of closures being produced and evaluated for any single lifting. I
> had a look at the Jane Street blog post about variable argument functions
> (http://ocaml.janestcapital.com/?q=node/22), which seems to do similar
> things. However I have never been really good with CPS, so I don't know if
> those techniques can be applied to this problem.
>
> Is there any way to do this, which does not get this ugly. Also the
> resulting lifted function should not contain too many closures.
>
> Thanks for your help,
>   Till
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>