From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id A8F9ABC37 for ; Fri, 16 Oct 2009 17:22:41 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AqMCADss2ErRVd+smGdsb2JhbACPVYsBPwEBAQEJCQwHE64ihl2IZQEDAwWEKwSBW4Upggc X-IronPort-AV: E=Sophos;i="4.44,574,1249250400"; d="scan'208";a="36485663" Received: from mail-iw0-f172.google.com ([209.85.223.172]) by mail3-smtp-sop.national.inria.fr with ESMTP; 16 Oct 2009 17:22:40 +0200 Received: by iwn2 with SMTP id 2so1150427iwn.1 for ; Fri, 16 Oct 2009 08:22:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:sender:received:in-reply-to :references:date:x-google-sender-auth:message-id:subject:from:to:cc :content-type:content-transfer-encoding; bh=gmGLnSMb2wvSL/iPcZRBsupuSG+pqHzOhC03AdlYDlQ=; b=SM3JJaumCrCHoRGFfNuu5ATxlJpfF4sIsNXVDtk3kJD7PedE/Adqe+VW0HsQSaoqeG 4a0emMgLgbbyk8v4/YcaHBZU3UgpA8pQOD53yl/MmZ4deuebnt/mPKsZpX0V+UjXp9MT tXFqdZ+nMUtwiR5lpPivZVRi95eC0Ri18MqB0= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type :content-transfer-encoding; b=cY5UtdwEdJWzjCHZkrzsv7noJMFwTPmkPGMLhPR9Vyd3nnwPvIFi5jVeUq2AkGrRh0 WV8pkQPwRy//XFOjwN4j30DT7kws8BsagBUInz/dvyPuSKv3HmS4y8Sze9hpZplfh4w5 LetJX3U8PvYGoOQKpsHuSPHhfCI8hiyh3IViM= MIME-Version: 1.0 Sender: till.varoquaux@gmail.com Received: by 10.231.125.100 with SMTP id x36mr5058344ibr.52.1255706560110; Fri, 16 Oct 2009 08:22:40 -0700 (PDT) In-Reply-To: <9d3ec8300910160815n76a47727h7f5bf13623f18125@mail.gmail.com> References: <9d3ec8300910160815n76a47727h7f5bf13623f18125@mail.gmail.com> Date: Fri, 16 Oct 2009 11:22:39 -0400 X-Google-Sender-Auth: a04f1e4ccaa8b841 Message-ID: <9d3ec8300910160822t4357c44ex4beb4f6401420bbd@mail.gmail.com> Subject: Re: [Caml-list] How to add () to function parameters From: Till Varoquaux To: Till Crueger Cc: caml-list@yquem.inria.fr Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Spam: no; 0.00; val:01 unparsing:01 danvy:01 abstracting:01 printf:01 scanf:01 brics:01 ocaml:01 node:01 beginner's:01 ocaml:01 bug:01 2009:98 countless:98 2009:98 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 wrot= e: > 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 = =3D > > that takes a three argument function a returns the same function in CPS s= tyle. > > The functional unparsing/danvy way [1]: > >> let (++) f g =3D fun x -> f (g x) >> let i k f arg =3D k (f arg) >> let cps ty ~f k =3D ty k f >> let cps3 ~f =3D cps (i++i++i) ~f > > brute force style: > >> let e acc ~f cont =3D acc cont f >> let i =3D fun acc g -> g (fun cont v arg -> acc cont (v arg)) >> let cps =3D fun z -> >> =C2=A0 let acc =3D (fun cont x -> cont x) in >> =C2=A0 z acc >> let cps3 ~f =3D 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 wrot= e: >> 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 thi= s is >> fairly easy and I can just do: >> >> let lift1 f a =3D >> =C2=A0 fun () -> >> =C2=A0 =C2=A0 =C2=A0f a;; >> >> let lift2 f a b =3D >> =C2=A0 fun () -> >> =C2=A0 =C2=A0 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... S= o >> 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 =3D >> =C2=A0 fun () -> >> =C2=A0 =C2=A0 =C2=A0f a;; >> >> let lift_more f a =3D >> =C2=A0 fun () -> >> =C2=A0 =C2=A0 =C2=A0f () 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 the= re >> are a lot of closures being produced and evaluated for any single liftin= g. I >> had a look at the Jane Street blog post about variable argument function= s >> (http://ocaml.janestcapital.com/?q=3Dnode/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, >> =C2=A0 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 >> >