* How to add () to function parameters
@ 2009-10-14 10:44 Till Crueger
2009-10-16 15:15 ` [Caml-list] " Till Varoquaux
0 siblings, 1 reply; 3+ messages in thread
From: Till Crueger @ 2009-10-14 10:44 UTC (permalink / raw)
To: caml-list
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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Caml-list] How to add () to function parameters
2009-10-14 10:44 How to add () to function parameters Till Crueger
@ 2009-10-16 15:15 ` Till Varoquaux
2009-10-16 15:22 ` Till Varoquaux
0 siblings, 1 reply; 3+ messages in thread
From: Till Varoquaux @ 2009-10-16 15:15 UTC (permalink / raw)
To: Till Crueger; +Cc: caml-list
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
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Caml-list] How to add () to function parameters
2009-10-16 15:15 ` [Caml-list] " Till Varoquaux
@ 2009-10-16 15:22 ` Till Varoquaux
0 siblings, 0 replies; 3+ messages in thread
From: Till Varoquaux @ 2009-10-16 15:22 UTC (permalink / raw)
To: Till Crueger; +Cc: caml-list
Oh, and I nearly forgot: In practice you shouldn't really have that
many functions taking more than 5 unlabeled arguments lying around so
I would bite the bullet and define cps1 through 5 the straightforward
way....
Till
On Fri, Oct 16, 2009 at 11:15 AM, Till Varoquaux <till@pps.jussieu.fr> wrote:
> 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
>>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-10-16 15:22 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-14 10:44 How to add () to function parameters Till Crueger
2009-10-16 15:15 ` [Caml-list] " Till Varoquaux
2009-10-16 15:22 ` Till Varoquaux
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox