Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does "reset" require "shift" inside the block?

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?

like image 509
Michael Avatar asked May 15 '11 08:05

Michael


1 Answers

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]
like image 143
tenshi Avatar answered Sep 30 '22 03:09

tenshi