« Return to Thread: [scala] Simulating python yield with scala continuations

Re: [scala] Simulating python yield with scala continuations

by Arnold deVos-3 :: Rate this Message:

Reply to Author | View in Thread

Well yes, you can always string together pieces with append, andThen and so on
but continuations are all about coding this sort of thing in direct-style.  
The benefit is not so clear with a simple example like mine.

But the point of the post is not to motivate continuations.  I am wanting
exchange knowledge with others that already do want to continuations and tease
out bugs in the implementation.

-- Arnold


On Thu, 18 Jun 2009 01:33:57 pm Jorge Ortiz wrote:

> Scala has lazy collections, which, AFAIK, can do whatever generators can
> without needing the continuations plugin.
>
>   val generate =
>     (
>       Array("first").projection append
>       (1 to 4).map(_.toString) append
>       Array("last").projection
>     ).elements
>
>   for (r <- generate) println(r)
>
> The code is, admittedly, a little ugly, but could be made a little cleaner
> with 2.8 collections.
>
> (Note this won't work in the interpreter, as the interpreter calls toString
> on "generate", which forces its evaluation. If you suppress the call to
> toString, it works as specified.)
>
> --j
>
> On Wed, Jun 17, 2009 at 7:17 PM, Arnold deVos <
>
> adv-list-scala@...> wrote:
> > I'm interested in the upcoming continuations support so I thought I would
> > try
> > to build something similar to the python generators with it.  Here is a
> > scrap
> > of python:
> >
> > def generate():
> >    yield "first"
> >    for i in range(1,4):
> >        yield str(i)
> >    yield "last"
> >
> > In python this function returns an iterator over the values passed to the
> > yield statements. The nice thing is: it is lazy and can be used as a
> > coroutine.  Anyway, if we iterate like this:
> >
> > for r in generate():
> >    print r
> >
> > It prints this:
> >
> > first
> > 1
> > 2
> > 3
> > last
> >
> > Here is a scala version in which a produce() method serves the same role
> > as python's yield:
> >
> > object Generator {
> >    def generate = {
> >        val g = new Generator[String]
> >        reset {
> >            g produce "first"
> >            g produce 1.toString
> >            g produce 2.toString
> >            g produce 3.toString
> >            g produce "last"
> >        }
> >        g
> >    }
> >
> >    def main(args: Array[String]) {
> >        for( a <- generate ) println(a)
> >    }
> > }
> >
> > This also prints
> >
> > first
> > 1
> > 2
> > 3
> > last
> >
> > The Generator class is defined in terms of shift() as follows:
> >
> > class Generator[A] extends Iterator[A] {
> >    private var a: A = _
> >    private var k: (Unit => Unit) = null
> >
> >    def next = {
> >        val a0 = a
> >        val k0 = k
> >        k = null
> >        k0()
> >        a0
> >    }
> >
> >    def hasNext = k != null
> >
> >    def produce(a0: A): Unit @ suspendable = {
> >        a = a0
> >        shift { k0: (Unit => Unit) => k = k0 }
> >    }
> > }
> >
> > But the example is not quite the same as the python because that had a
> > loop in
> > the generate function.  Lets try that in the scala version, replacing the
> > generate method with:
> >
> >    def generate = {
> >        val g = new Generator[String]
> >        reset {
> >            g produce "first"
> >            for( i <- 1 to 4) { g produce i.toString }
> >            g produce "last"
> >        }
> >        g
> >    }
> >
> > But this does not compile:
> >
> > generator.scala:28: error: type mismatch;
> >  found   : (Int) => Unit @scala.continuations.cps[Unit,Unit]
> >  required: (Int) => Unit
> >            for( i <- 1 to 4) { g produce i.toString }
> >                 ^
> > one error found
> >
> > Substituting a while loop produces a different compile error. Do any
> > continuation experts/experimenters out there know what the problem is?
> >
> > The example was compiled with scala r17271 plus the latest continuations
> > plugin from trunk as of r18035 for reasons explained in the previous
> > post. This may be the problem, I don't know.
> >
> > - Arnold


 « Return to Thread: [scala] Simulating python yield with scala continuations