Bah. I'd played with C#'s yield and not worked out how to make it
This one's probably most useful as a compiler test case though. :)
> As a side note, I think the point with Python's generators is best given
> with tree traversal:
>
> def inorder(t):
> if t:
> for x in inorder(t.left):
> yield x
> yield t.label
> for x in inorder(t.right):
> yield x
>
> No explicit state management, no result building up. As soon as I have a
> value, I yield it.
>
> On Jun 18, 2009, at 6:56 AM, Arnold deVos wrote:
>
>> 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
>>
>>
>
> --
> __~O
> -\ <, Christos KK Loverdos
> (*)/ (*)
http://ckkloverdos.com>
>
>
>
>
>