This class represent a portion of computation that has a 'hole' in it.
This class represent a portion of computation that has a 'hole' in it. The
class has the ability to compute state up until a certain point where the
state has the A
type. If this context is given a function of type
A => B
to move the state to the B
type, then the entire computation can
be completed resulting in a value of type C
.
An Example:
val cc = new ControlContext[String, String, String]( fun = { (f: String=>String, err: Exception => String) => val updatedState = try f("State") catch { case e: Exception => err(e) } updatedState + "-Complete!" }, x = null.asIntanceOf[String] } cc.foreach(_ + "-Continued") // Results in "State-Continued-Complete!"
This class is used to transform calls to shift
in the continuations
package. Direct use and instantiation is possible, but usually reserved
for advanced cases.
A context may either be trivial or non-trivial. A trivial
context just has a state of type A
. When completing the computation,
it's only necessary to use the function of type A => B
directly against
the trivial value. A non-trivial value stores a computation around
the state transformation of type A => B
and cannot be short-circuited.
The type of the state currently held in the context.
The type of the transformed state needed to complete this computation.
The return type of the entire computation stored in this context.
fun
and x
are allowed to be null
.
scala.util.continutations.shiftR
An annotation that denotes a type is part of a continuation context.
An annotation that denotes a type is part of a continuation context.
@cps[A]
is shorthand for cpsParam[A,A]
.
This annotation is used to mark a parameter as part of a continuation context.
This annotation is used to mark a parameter as part of a continuation context.
The type A @cpsParam[B,C]
is desugared to ControlContext[A,B,C]
at compile
time.
The type of computation state after computation has executed, and before control is returned to the shift.
The eventual return type of this delimited compuation.
scala.util.continuations.ControlContext
An annotation that denotes a type is part of a side effecting continuation context.
An annotation that denotes a type is part of a side effecting continuation context.
@suspendable
is shorthand notation for @cpsParam[Unit,Unit]
or @cps[Unit]
.
This method converts from the sugared A @cpsParam[B,C]
type to the desugared
ControlContext[A,B,C]
type.
This method converts from the sugared A @cpsParam[B,C]
type to the desugared
ControlContext[A,B,C]
type. The underlying data is not changed.
Creates a context for continuations captured within the argument closure
of this reset
call and returns the result of the entire transformed
computation.
Creates a context for continuations captured within the argument closure
of this reset
call and returns the result of the entire transformed
computation. Within an expression of the form reset { block }
,
the closure expression (block
) will be modified such that at each
call to shift
the remainder of the expression is transformed into a
function to be passed into the shift.
The result of a block of code that uses shift
to capture continuations.
The shift
function captures the remaining computation in a reset
block
and passes it to a closure provided by the user.
The shift
function captures the remaining computation in a reset
block
and passes it to a closure provided by the user.
For example:
reset { shift { (k: Int => Int) => k(5) } + 1 }
In this example, shift
is used in the expression shift ... + 1
.
The compiler will alter this expression so that the call
to shift
becomes a parameter to a function, creating something like:
{ (k: Int => Int) => k(5) } apply { _ + 1 }
The result of this expression is 6.
There can be more than one shift
call in a reset
block. Each call
to shift
can alter the return type of expression within the reset block,
but will not change the return type of the entire reset { block }
expression.
A function where
reset
block. This is passed as a function A => B
.ControlContext
which is
generated from this inversion.Must be invoked in the context of a call to reset
This context
may not be far up the stack, but a call to reset is needed to
eventually remove the @cps
annotations from types.
Captures a computation into a ControlContext
.
Captures a computation into a ControlContext
.
The function which accepts the inverted computation and returns a final result.
shift
Delimited continuations are a feature for modifying the usual control flow of a program. To use continuations, provide the option
-P:continuations:enable
to the Scala compiler or REPL to activate the compiler plugin.Below is an example of using continuations to suspend execution while awaiting user input. Similar facilities are used in so-called continuation-based web frameworks.
The
reset
is provided by this package and delimits the extent of the transformation. Theask
is a function that will be defined below. Its effect is to issue a prompt and then suspend execution awaiting user input. Once the user provides an input value, execution of the suspended block resumes.The type of
ask
includes a@cps
annotation which drives the transformation. The type signatureInt @cps[Unit]
means thatask
should be used in a context requiring anInt
, but actually it will suspend and returnUnit
.The computation leading up to the first
ask
is executed normally. The remainder of the reset block is wrapped into a closure that is passed as the parameterk
to theshift
function, which can then decide whether and how to execute the continuation. In this example, the continuation is stored in a sessions map for later execution. This continuation includes a second call toask
, which is treated likewise once the execution resumes.CPS Annotation
The aforementioned
@cps[A]
annotation is an alias for the more general@cpsParam[B,C]
whereB=C
. The typeA @cpsParam[B,C]
describes a term which yields a value of typeA
within an evaluation context producing a value of typeB
. After the CPS transformation, this return type is modified toC
.The
@cpsParam
annotations are introduced byshift
blocks, and propagate via the return types to the dynamically enclosing context. The propagation stops upon reaching areset
block.