This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Problem of scala continuation

2 replies
Zealot
Joined: 2010-11-01,
User offline. Last seen 1 year 51 weeks ago.
I have written a simple scala echo server using scala continuation here (http://gist.github.com/659295)
I got problem when use shift inside while loop, consider following code
    var i = 0    reset {      while (i < 10) {        println("Loop: " + i)         i += 1        if (true)          shift { k: (Unit => Unit) => k() }      }    }
this won't compile
<console>:14: error: type mismatch; found   : Unit required: Unit @scala.util.continuations.cpsParam[Unit,Unit]               if (true)               ^
but with a define of cpsWhile here
    case class x(condition: Unit => Boolean) {      def apply(x: => Unit @cps[Unit]): Unit @cps[Unit] = while (condition()) x     }    def cpsWhile(condition: => Boolean) = x({ _ => condition })
then replace `while' with this cpsWhile
    var i = 0     reset {      cpsWhile(i < 10) {        println("Loop: " + i)        i += 1        if (true)          shift { k: (Unit => Unit) => k() }       }    }
now this code works.
I have tried scala 2.8.0.final, 2.8.1.RC4 and nightly 2.9.0.r23417-b20101101020019, none of them works well, Is there any way to improve it ?
Colin Bullock
Joined: 2009-01-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Problem of scala continuation
The problem is the shift inside an if statement without an else.

The following should also solve the problem:

    def cpsunit: Unit @cps[Unit] = ()
     var i = 0    reset {       while (i < 10) {        println("Loop: " + i)         i += 1        if (true) shift { k: (Unit => Unit) => k() }
        else cpsunit
      }    }


- Colin

Zealot
Joined: 2010-11-01,
User offline. Last seen 1 year 51 weeks ago.
Re: Problem of scala continuation

After dig into the source code, I still have some question

But the compiler refuse to convert Unit to Unit @cps[Unit]. Because
if-the-else take
params in BYVALmode, and AnnotationChecker of continuation don't convert any
expr in BYVALmode.

Here is something confused me.
1. Why if-then-else is BYVALmode. If write if-clause using match/case
it is obviously by-name
def if[R](cond: Boolean)(x: => R, y: => R) = cond match {
case true => x
case false => y
}
is there any optimization when put if-clause inside while loop ?

2. Why can't do this pure to impure convert in BYVALmode ?
In paper continuation-icfp09, it is said "pure expressions can be
treated as impure
ones that do not change the answer type".

Γ ⊢(pure)e:τ => Γ ;α⊢e:τ;α

I think it means type A can be can be implicit converted to type A
@cpaParam[A, ?].

P.S. the following code works, as () is passed to cpsIf by-name, and
can be converted implicit

def cpsIf[A, B, C](cond: Boolean)(x: => A @cpsParam[B, C], y: => A
@cpsParam[B, C]) = cond match {
case true => x
case false => y
}

var i = 0
reset {
while (i < 10) {
println("Loop: " + i)
i += 1
cpsIf[Unit, Unit, Unit](true)(shift { k: (Unit => Unit) => k() }, ())
}
}

Thanks for your explanation.

On Wed, Nov 3, 2010 at 1:01 AM, Colin Bullock wrote:
> The problem is the shift inside an if statement without an else.
>
> The following should also solve the problem:
>
>     def cpsunit: Unit @cps[Unit] = ()
>
>     var i = 0
>     reset {
>       while (i < 10) {
>         println("Loop: " + i)
>         i += 1
>         if (true) shift { k: (Unit => Unit) => k() }
>         else cpsunit
>       }
>     }
>
>
> - Colin
>
>

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland