<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE message PUBLIC
  "-//MLarc//DTD MLarc output files//EN"
  "../../mlarc.dtd"[
  <!ATTLIST message
    listname CDATA #REQUIRED
    title CDATA #REQUIRED
  >
]>

  <?xml-stylesheet href="../../mlarc.xsl" type="text/xsl"?>


<message 
  url="2009/10/4def6cb1b0cb5eb0931e86bb5de2c977"
  from="Till Varoquaux &lt;till@p...&gt;"
  author="Till Varoquaux"
  date="2009-10-16T15:15:08"
  subject="Re: [Caml-list] How to add () to function parameters"
  prev="2009/10/65b9b392d5779a94893ecea98ce9dbe0"
  next="2009/10/e9ad3c0b25d3628d64545506e6804dda"
  prev-in-thread="2009/10/67acf39883f97441f08e61ecd49a77e2"
  next-in-thread="2009/10/e9ad3c0b25d3628d64545506e6804dda"
  prev-thread="2009/10/6d8097dd50dc4197e62e77c76987d947"
  next-thread="2009/10/05e52ba550a618e67da7434c75334d50"
  root="../../"
  period="month"
  listname="caml-list"
  title="Archives of the Caml mailing list">

<thread subject="How to add () to function parameters">
<msg 
  url="2009/10/67acf39883f97441f08e61ecd49a77e2"
  from="Till Crueger &lt;Till.Crueger@g...&gt;"
  author="Till Crueger"
  date="2009-10-14T10:40:58"
  subject="How to add () to function parameters">
<msg 
  url="2009/10/4def6cb1b0cb5eb0931e86bb5de2c977"
  from="Till Varoquaux &lt;till@p...&gt;"
  author="Till Varoquaux"
  date="2009-10-16T15:15:08"
  subject="Re: [Caml-list] How to add () to function parameters">
<msg 
  url="2009/10/e9ad3c0b25d3628d64545506e6804dda"
  from="Till Varoquaux &lt;till@p...&gt;"
  author="Till Varoquaux"
  date="2009-10-16T15:22:41"
  subject="Re: [Caml-list] How to add () to function parameters">
</msg>
</msg>
</msg>
</thread>

<contents>
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 -&gt; 'b -&gt; 'c -&gt; 'd) -&gt; ('d -&gt; 'e) -&gt; 'a -&gt; 'b -&gt; 'c -&gt; 'e =

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

The functional unparsing/danvy way [1]:

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

brute force style:

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

</contents>

</message>

