- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Problem of scala continuation
Tue, 2010-11-02, 12:28
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 ?
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 ?
Fri, 2010-11-05, 14:37
#2
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
>
>
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