caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Mutually recursive closures?
@ 2011-09-09 23:14 Anthony Tavener
  2011-09-09 23:31 ` Jonathan Protzenko
  0 siblings, 1 reply; 5+ messages in thread
From: Anthony Tavener @ 2011-09-09 23:14 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 1161 bytes --]

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

[-- Attachment #2: Type: text/html, Size: 1515 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] Mutually recursive closures?
  2011-09-09 23:14 [Caml-list] Mutually recursive closures? Anthony Tavener
@ 2011-09-09 23:31 ` Jonathan Protzenko
  2011-09-10  0:47   ` Anthony Tavener
  0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Protzenko @ 2011-09-09 23:31 UTC (permalink / raw)
  To: Anthony Tavener; +Cc: caml-list

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
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] Mutually recursive closures?
  2011-09-09 23:31 ` Jonathan Protzenko
@ 2011-09-10  0:47   ` Anthony Tavener
  2011-09-10  6:54     ` Philippe Veber
  0 siblings, 1 reply; 5+ messages in thread
From: Anthony Tavener @ 2011-09-10  0:47 UTC (permalink / raw)
  To: Jonathan Protzenko; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 2056 bytes --]

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
>>
>>

[-- Attachment #2: Type: text/html, Size: 2689 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] Mutually recursive closures?
  2011-09-10  0:47   ` Anthony Tavener
@ 2011-09-10  6:54     ` Philippe Veber
  2011-09-10 10:33       ` Anthony Tavener
  0 siblings, 1 reply; 5+ messages in thread
From: Philippe Veber @ 2011-09-10  6:54 UTC (permalink / raw)
  To: Anthony Tavener; +Cc: Jonathan Protzenko, caml-list

[-- Attachment #1: Type: text/plain, Size: 2926 bytes --]

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 <fun>
val b : t = F <fun>
# let ( ! ) (F f) = f ();;
val ( ! ) : t -> t = <fun>
# let x1 = ! a;;
a
val x1 : t = F <fun>
# ! x1;;
b
- : t = 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 = 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 <anthony.tavener@gmail.com>

> 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
>>>
>>>
>

[-- Attachment #2: Type: text/html, Size: 5875 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] Mutually recursive closures?
  2011-09-10  6:54     ` Philippe Veber
@ 2011-09-10 10:33       ` Anthony Tavener
  0 siblings, 0 replies; 5+ messages in thread
From: Anthony Tavener @ 2011-09-10 10:33 UTC (permalink / raw)
  To: Philippe Veber; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 3445 bytes --]

That's a good alternative, thanks Philippe! I might use this, but
encapsulate the returned closures with the constructor since they will be of
common type -- whereas the function signatures will be different, some
having additional parameters.

I've read more on rectypes and it's certainly not to be used lightly!


On Sat, Sep 10, 2011 at 12:54 AM, Philippe Veber
<philippe.veber@gmail.com>wrote:

> 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 <fun>
> val b : t = F <fun>
> # let ( ! ) (F f) = f ();;
> val ( ! ) : t -> t = <fun>
> # let x1 = ! a;;
> a
> val x1 : t = F <fun>
> # ! x1;;
> b
> - : t = 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 = 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 <anthony.tavener@gmail.com>
>
>> 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
>>>>
>>>>
>>
>

[-- Attachment #2: Type: text/html, Size: 6601 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-09-10 10:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-09 23:14 [Caml-list] Mutually recursive closures? Anthony Tavener
2011-09-09 23:31 ` Jonathan Protzenko
2011-09-10  0:47   ` Anthony Tavener
2011-09-10  6:54     ` Philippe Veber
2011-09-10 10:33       ` Anthony Tavener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).