Is it correct that reset requires shift inside the block? I tried it and got the following:
scala> reset {}
error: cannot cps-transform expression (): type arguments [Unit,Unit,Nothing]
do not conform to method shiftUnit's type parameter bounds [A,B,C >: B]
It looks reasonable (since reset block without shift inside is "dead code", which is never executed) but I do not understand the error.
What is the exact meaning of the error message?
I don't agree, that code within reset is dead without shift. Actually reset just defines the boundaries of a continuation (that's because they are called delimited continuations).The code would be dead if you have shift somewhere within reset and you do not call continuation function. For example:
reset {
println(1)
shift((k: Unit => Unit) => println(2))
println(3)
}
The code after shift is dead (println(3)) because I have not called k(Unit).
From the other hand, seems that reset expects some special return type from it's body - the one that annotated with @cpsParam annotation. You can check definition of reset method:
def reset[A,C](ctx: => (A @cpsParam[A,C])): C = ...
And shift produces just what reset method expects. Here is definition of shift method:
def shift[A,B,C](fun: (A => B) => C): A @cpsParam[B,C] = ...
But you still can use reset without shift call within it. This trick will do it:
def foo[T](body: => T @cps[Any]) = reset(body)
foo {
println("it works")
}
Please note, that @cps is just type alias for @cpsParam. Here it's definition:
type cps[A] = cpsParam[A, A]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With