From mboxrd@z Thu Jan 1 00:00:00 1970 X-Sympa-To: caml-list@inria.fr Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p8A6tN1O013347 for ; Sat, 10 Sep 2011 08:55:23 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Am0BALEIa07RVdQ0imdsb2JhbABCpxp3CBQBAQEKCQ0HEgYigVIBAQEBAgESAhMZARsdAQMBCwYFCw0uIQEBEQEFARwGEyKHVJhkCol6gUSCV4URO4htAgMGhmgEkzuKCIJsPYNu X-IronPort-AV: E=Sophos;i="4.68,360,1312149600"; d="scan'208";a="119109262" Received: from mail-vw0-f52.google.com ([209.85.212.52]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 10 Sep 2011 08:55:17 +0200 Received: by vws16 with SMTP id 16so2761903vws.11 for ; Fri, 09 Sep 2011 23:55:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=nbY+WLWEErz/g2WMx7H7GXVPqwwxk/k3Fj5Fb6oEhQ4=; b=nwMVlNqzN4X/p3Jmrc2OfHcVqp5uPg9ju5pKG6NhTn0Lg5F2iKuZFG7EbTwGKEzVoi fx6Zt5hACGVAOvoQWBeCphlfG3wPN7eZqhRHRmbxsClFyFdLJ/AQYjGRKkSBLYK6Cj2F Kq0zHtb4+TB2Ff+mxW+MvI3VsOyQgUVWifhyU= Received: by 10.52.101.227 with SMTP id fj3mr1534000vdb.367.1315637716424; Fri, 09 Sep 2011 23:55:16 -0700 (PDT) MIME-Version: 1.0 Received: by 10.221.13.202 with HTTP; Fri, 9 Sep 2011 23:54:56 -0700 (PDT) In-Reply-To: References: <4E6AA1E1.9050307@gmail.com> From: Philippe Veber Date: Sat, 10 Sep 2011 08:54:56 +0200 Message-ID: To: Anthony Tavener Cc: Jonathan Protzenko , caml-list@inria.fr Content-Type: multipart/alternative; boundary=bcaec5485c94bd969d04ac90c649 X-Validation-by: philippe.veber@gmail.com Subject: Re: [Caml-list] Mutually recursive closures? --bcaec5485c94bd969d04ac90c649 Content-Type: text/plain; charset=ISO-8859-1 You may not need the -rectypes option if you add a thin layer around your functions: Objective Caml version 3.12.1 Findlib has been successfully loaded. Additional directives: [...] # type t = F of (unit -> t);; type t = F of (unit -> t) # let rec a = F (fun () -> print_endline "a" ; b) and b = F (fun () -> print_endline "b" ; a);; val a : t = F val b : t = F # let ( ! ) (F f) = f ();; val ( ! ) : t -> t = # let x1 = ! a;; a val x1 : t = F # ! x1;; b - : t = F It works in this version because you're defining a brand new type, and not using a type alias (like in type t = unit -> t). I think a record would work too, but I think either is needed to avoid using -rectypes. cheers, Philippe. 2011/9/10 Anthony Tavener > Thanks Jonathan! I've seen -rectypes mentioned over the years and always > glossed over it thinking "Ah, I'll never need that!" :P > > Understandable that it's a good default to have disabled. I'll experiment > first and if I like the results I'll try to limit compiling with -rectypes > to the smallest bit of code using it. > > > On Fri, Sep 9, 2011 at 5:31 PM, Jonathan Protzenko < > jonathan.protzenko@gmail.com> wrote: > >> You can use equirecursive types, which can be enabled through the >> -rectypes command-line switch. With that option, your example above >> type-checks. However, these are not enabled by default for a variety of >> reasons, the most important one being it makes it much easier to shoot >> yourself in the foot. >> >> Cheers, >> >> jonathan >> >> >> On Sat 10 Sep 2011 01:14:46 AM CEST, Anthony Tavener wrote: >> >>> I was considering returning a couple of closures to help organize my UI >>> code, essentially representing current UI mode by one of these closures. But >>> then I run into a problem because the types are infinite (returns a >>> function, which returns a function, ...) >>> >>> A simplified example: >>> >>> # let rec a () = printf "state a\n"; b >>> and b () = printf "state b\n"; a >>> >>> Error: This expression has type unit -> unit -> 'a >>> but an expression was expected of type 'a >>> >>> >>> Is there a way I can do this? To express (or 'hide') the cyclic nature of >>> the type resolution? >>> >>> I've considered using continuations, but that seems heavy-weight for what >>> I'm looking to do. And as far as I can tell I'd need to leverage Oleg's >>> delimcc (which I'd love to start using and wrap my head around -- but for a >>> task worthy of it!). >>> >>> I can use a variant to represent states/modes and have a dispatcher which >>> runs the right code... but this introduces what feels like an unnecessary >>> layer of distraction. Returning the closure of the "next state" seems >>> straightforward, but introduces cycles into the typing. :( >>> >>> I'm hoping I'm missing something simple. Thank-you for any assistance! >>> >>> -Tony >>> >>> > --bcaec5485c94bd969d04ac90c649 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable You may not need the -rectypes option if you add a thin layer around your f= unctions:

=A0=A0=A0=A0=A0=A0=A0 Objective Ca= ml version 3.12.1

Findlib has been successfully loaded. Additional= directives:
[...]
# type t =3D F o= f (unit -> t);;
= type t =3D F of (unit -= > t)
# let rec a =3D F (fun = () -> print_endline "a" ; b)
= =A0 and=A0=A0=A0=A0 b =3D F (fun () -> print_endline "b" ; a);= ;
val a : t =3D F <fun= >
val b : t =3D F <fun> # let ( ! ) (F f) =3D f= ();;
val ( ! ) : t -> t =3D <fun&= gt;
# let x1 =3D ! a;;
a
val x1 : t =3D F <fu= n>
# ! x1;;
b
- : t =3D F <fun>

It works in this version because you're defining a brand new type, = and not using a type alias (like in type t =3D unit -> t). I think a rec= ord would work too, but I think either is needed to avoid using -rectypes.<= br>
cheers,
=A0 Philippe.



2011/9/1= 0 Anthony Tavener <anthony.tavener@gmail.com>
Thanks Jonathan! I've seen -rectypes mentioned over the years and alway= s glossed over it thinking "Ah, I'll never need that!" :P
Understandable that it's a good default to have disable= d. I'll experiment first and if I like the results I'll try to limi= t compiling with -rectypes to the smallest bit of code using it.


On Fri, Sep 9, 2011 at 5= :31 PM, Jonathan Protzenko <jonathan.protzenko@gmail.com>= ; wrote:
You can use equirecursive types, which can be enabled through the -rectypes= command-line switch. With that option, your example above type-checks. How= ever, these are not enabled by default for a variety of reasons, the most i= mportant one being it makes it much easier to shoot yourself in the foot.
Cheers,

jonathan


On Sat 10 Sep 2011 01:14:46 AM CEST, Anthony Tavener wrote:
I was considering returning a couple of closures to help organize my UI cod= e, essentially representing current UI mode by one of these closures. But t= hen I run into a problem because the types are infinite (returns a function= , which returns a function, ...)

A simplified example:

# let rec a () =3D printf "state a\n"; b
=A0 =A0 =A0 and b () =3D printf "state b\n"; a

Error: This expression has type unit -> unit -> 'a
=A0 =A0 =A0 but an expression was expected of type 'a


Is there a way I can do this? To express (or 'hide') the cyclic nat= ure of the type resolution?

I've considered using continuations, but that seems heavy-weight for wh= at I'm looking to do. And as far as I can tell I'd need to leverage= Oleg's delimcc (which I'd love to start using and wrap my head aro= und -- but for a task worthy of it!).

I can use a variant to represent states/modes and have a dispatcher which r= uns the right code... but this introduces what feels like an unnecessary la= yer of distraction. Returning the closure of the "next state" see= ms straightforward, but introduces cycles into the typing. :(

I'm hoping I'm missing something simple. Thank-you for any assistan= ce!

=A0-Tony



--bcaec5485c94bd969d04ac90c649--