Recursive datatype and gcc error

See:

The trick is to use the following annotation to pass the proper type
information on f to the compiler:

val f = f : coroutine_clo (i, o)

This has something to do with the way typechecking in ATS is implemented;
it is not easy to fix.

ok,
does it work also in ATS 1 ? I think I tried to make specialized version of
viewt@ype bases but it didn’t work :frowning:

I have also concerns regarding memory management. I would like to make a
coroutine free function that delete a coroutine not yet called.

my sample :

absviewtype
coroutine_vt (inp: vt0p, out: vt0p) = ptr

viewtypedef lcfun1
(a:vt0p, b:vt0p) = (a) -<lin,cloptr1> b

viewtypedef cfun1
(a:vt0p, b:vt0p) = (a) - b

extern fun{a,b: vt0p} co_run(co: coroutine_vt(a, b), x: a): (b,coroutine_vt(
a,b))
extern fun{a,b,c: vt0p} co_fmap(co: coroutine_vt(a,b), f: cfun1(b,c)):coroutine_vt
(a,c)

//extern fun{a,b: vt0p} co_free(co: coroutine_vt(a, b)): void

extern castfn coroutine_of_linc {a, b: vt0p}
(cf: lcfun1 (a, @(b, coroutine_vt (a, b)))):<> coroutine_vt (a, b)

extern castfn linc_of_coroutine {a, b:vt0p}
(co: coroutine_vt (a, b)):<> lcfun1 (a, @(b, coroutine_vt (a, b)))

implement{a,b} co_run(co, x) = res where {
val f = linc_of_coroutine{a, b}(co)
val res = f x
val () = cloptr_free (f)
}

//implement{a,b} co_free(co) = let
// val ptr = linc_of_coroutine{a, b}(co)
//in
// cloptr_free ptr
//end

implement{a,b,c} co_fmap(co, f) = coroutine_of_linc{a,c}(llam x =let
val (x’, co’) = co_run<a,b>(co, x)
in
(f(x’), co_fmap<a,b,c>(co’, f))
end)

extern fun ints_from (x: int): coroutine_vt (unit, int)
implement ints_from(x) = coroutine_of_linc{unit,int}(llam _ => (x,ints_from
(x+1)))

implement main() = let
extern castfn __leak {v:view} (pf: v):<> void

val co = ints_from 0
fun add1(x: int): int = x + 1
val co1 = co_fmap<unit,int,int>(co, add1)
val () = cloptr_free add1
val (x, co2) = co_run(co1, unit)
val () = printf("%d\n", @(x))
in
__leak co2
//co_free co2
end

As you can see I would like to be able to call co_free but this does not
compile. How can I could delete this coroutine ?

Thanks a lot :wink:

mmm this example is more relevant :

The co_arr_fanout implementation

extern fun{a,b: vt0p} co_arr(f: cfun1(a, b)): coroutine_vt(a, b)
extern fun{a,b,c: vt0p} co_arr_bind(cof: coroutine_vt(a, b), cog:coroutine_vt
(b, c)): coroutine_vt(a, c)
extern fun{a,b,c,d: vt0p} co_arr_combine(cof: coroutine_vt(a, b), cog:coroutine_vt
(c, d)): coroutine_vt((a, c), (b, d))

extern fun{a,b,c: vt0p} co_arr_fanout(cof: coroutine_vt(a, b), cog:coroutine_vt
(a, c)): coroutine_vt(a, (b,c))

implement{a,b,c} co_arr_fanout(cof, cog) = co_arr_bind(co_arr f,co_arr_combine
(cof, cog) ) where {
fun f (x: a): (a, a) = (x, x)
}

the problem with co_arr_fanout is that it must duplicate the input in two
channels.
I have the same “there is no type for the dynamic variable” error here.
How to duplicate a generic viewt@ype ?

does it work also in ATS 1 ? I think I tried to make specialized version
of viewt@ype bases but it didn’t work :frowning:

Most of it also works in ATS1. What does not work is the following style of
implementation:

implement(a)
co_arr_fanout_dup<event(a)> (x) = …

You could only do it for a fixed template argument:

implement
co_arr_fanout_dup<event(T)> (x) = …

where T is a closed type like int, float, etc.

I would like to make a coroutine free function that delete a coroutine
not yet called.

I knew you would ask this question sooner or later :slight_smile:

Unfortunately, this cannot be done (or done safely) if coroutine_vt is
implemented as a closure.
Say you have a coroutine cof; in order to free cof, you may need to free
other coroutines contained
in the environment of cof. For instance, linear thunks (for
lazy-evaluation) in ATS1 are implemented
in a way that allows them to be properly freed. To do this, some form of
support from the compiler
seems to be needed. Maybe we could do this for coroutines in the future.

thanks,
I have found an ugly solution consisting in implementing arrows
specifically for event_vt viewtype :

the fanout case was :

extern fun{a,b,c: t@ype} co_arr_fanout(cof: coroutine_vt(a, b), cog:coroutine_vt
(a, c)): coroutine_vt(a, (b,c))

becomes :

extern fun{a,b,c: t@ype} co_arr_event_vt_fanout(cof: coroutine_vt(event_vt a
, event_vt b), cog: coroutine_vt(event_vt a, event_vt c)): coroutine_vt(event_vt
a, (event_vt b, event_vt c))

and I use a method to duplicate the event_vt viewtype (same as dup in forth
:wink: )

extern fun{a: t@ype} event_vt_dup(x: event_vt a): (event_vt a, event_vt a)

The ugly part is I lose all benefits of generics and I have to implement
all specific bindings between eventized arrows

The complete example can be found here
: https://github.com/cduret/ats_samples/blob/master/frp/lin/coroutinelin.dats

Hi,

Once you are familiar with ATS, you can declare coroutine as a linear
datatype (dataviewtype).
Then you truly get to see how beautiful this concept is :slight_smile: It is a pity
that Haskell people don’t get to see
the full beauty :frowning:

Probably for the reasons given here:
http://permalink.gmane.org/gmane.comp.lang.ats.user/523

That post also gives a workaround.

Posted for Chris Double chri...@gmail.com

Nice! I will try to port it to ATS2. I created a small project:

https://github.com/githwxi/ATS-Postiats/tree/master/doc/PROJECT/SMALL/coroutine

More later,

–Hongwei

thanks :wink:
Now I have moved to ats2 and everything works fine !