summaryrefslogtreecommitdiff
path: root/src/continuations
diff options
context:
space:
mode:
authorJosh Suereth <joshua.suereth@gmail.com>2011-09-18 13:28:55 +0000
committerJosh Suereth <joshua.suereth@gmail.com>2011-09-18 13:28:55 +0000
commitbfeef8a9d3015f1273dcda653fe4c20fdbc3f906 (patch)
tree85294383188034c6bd092cdb69857c4a025fcbcf /src/continuations
parent3f58f66c8b2147d728467da9ede91cdcf60a4a8d (diff)
downloadscala-bfeef8a9d3015f1273dcda653fe4c20fdbc3f906.tar.gz
scala-bfeef8a9d3015f1273dcda653fe4c20fdbc3f906.tar.bz2
scala-bfeef8a9d3015f1273dcda653fe4c20fdbc3f906.zip
Scaladoc enhancements to continuations package ...
Scaladoc enhancements to continuations package for docspree. Review by rompf
Diffstat (limited to 'src/continuations')
-rw-r--r--src/continuations/library/scala/util/continuations/ControlContext.scala87
-rw-r--r--src/continuations/library/scala/util/continuations/package.scala62
2 files changed, 142 insertions, 7 deletions
diff --git a/src/continuations/library/scala/util/continuations/ControlContext.scala b/src/continuations/library/scala/util/continuations/ControlContext.scala
index f183f99764..8059252f80 100644
--- a/src/continuations/library/scala/util/continuations/ControlContext.scala
+++ b/src/continuations/library/scala/util/continuations/ControlContext.scala
@@ -3,6 +3,17 @@
package scala.util.continuations
import annotation.{ Annotation, StaticAnnotation, TypeConstraint }
+/** This annotation is used to mark a parameter as part of a continuation
+ * context.
+ *
+ * The type `A @cps[B,C]` is desugared to `ControlContext[A,B,C]` at compile
+ * time.
+ *
+ * @tparam B The type of computation state after computation has executed, and
+ * before control is returned to the shift.
+ * @tparam C The eventual return type of this delimited compuation.
+ * @see scala.util.continuations.ControlContext
+ */
class cpsParam[-B,+C] extends StaticAnnotation with TypeConstraint
private class cpsSym[B] extends Annotation // implementation detail
@@ -13,7 +24,55 @@ private class cpsPlus extends StaticAnnotation with TypeConstraint // implementa
private class cpsMinus extends Annotation // implementation detail
-
+/**
+ * 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.
+ *
+ * @param fun The captured computation so far. The type
+ * `(A => B, Exception => B) => C` is a function where:
+ * - The first parameter `A=>B` represents the computation defined against
+ * the current state held in the ControlContext.
+ * - The second parameter `Exception => B` represents a computation to
+ * perform if an exception is thrown from the first parameter's computation.
+ * - The return value is the result of the entire computation contained in this
+ * `ControlContext`.
+ * @param x The current state stored in this context. Allowed to be null if
+ * the context is non-trivial.
+ * @tparam A The type of the state currently held in the context.
+ * @tparam B The type of the transformed state needed to complete this computation.
+ * @tparam C The return type of the entire computation stored in this context.
+ * @note `fun` and `x` are allowed to be `null`.
+ * @see scala.util.continutations.shiftR
+ */
final class ControlContext[+A,-B,+C](val fun: (A => B, Exception => B) => C, val x: A) extends Serializable {
/*
@@ -26,7 +85,12 @@ final class ControlContext[+A,-B,+C](val fun: (A => B, Exception => B) => C, val
}
*/
-
+ /**
+ * Modifies the currently captured state in this `ControlContext`.
+ * @tparam A1 The new type of state in this context.
+ * @param f A transformation function on the current state of the `ControlContext`.
+ * @return The new `ControlContext`.
+ */
@noinline final def map[A1](f: A => A1): ControlContext[A1,B,C] = {
if (fun eq null)
try {
@@ -55,6 +119,17 @@ final class ControlContext[+A,-B,+C](val fun: (A => B, Exception => B) => C, val
// it would be nice if @inline would turn the trivial path into a tail call.
// unfortunately it doesn't, so we do it ourselves in SelectiveCPSTransform
+ /**
+ * Maps and flattens this `ControlContext` with another `ControlContext` generated from the current state.
+ * @note: The resulting comuptation is still the type `C`.
+ * @tparam A1 The new type of the contained state.
+ * @tparam B1 The new type of the state after the stored continuation has executed.
+ * @tparam C1 The result type of the nested `ControlContext`. Because the nested `ControlContext` is executed within
+ * the outer `ControlContext`, this type must `>: B` so that the resulting nested computation can be fed through
+ * the current continuation.
+ * @param f A transformation function from the current state to a nested `ControlContext`.
+ * @return The transformed `ControlContext`.
+ */
@noinline final def flatMap[A1,B1,C1<:B](f: (A => ControlContext[A1,B1,C1])): ControlContext[A1,B1,C] = {
if (fun eq null)
try {
@@ -80,6 +155,11 @@ final class ControlContext[+A,-B,+C](val fun: (A => B, Exception => B) => C, val
}, null.asInstanceOf[A1])
}
+ /**
+ * Runs the computation against the state stored in this `ControlContext`.
+ * @param f the computation that modifies the current state of the context.
+ * @note This method could throw exceptions from the computations.
+ */
final def foreach(f: A => B) = foreachFull(f, throw _)
def foreachFull(f: A => B, g: Exception => B): C = {
@@ -89,8 +169,9 @@ final class ControlContext[+A,-B,+C](val fun: (A => B, Exception => B) => C, val
fun(f, g)
}
-
+ /** @return true if this context only stores a state value and not any deferred computation. */
final def isTrivial = fun eq null
+ /** @return The current state value. */
final def getTrivialValue = x.asInstanceOf[A]
// need filter or other functions?
diff --git a/src/continuations/library/scala/util/continuations/package.scala b/src/continuations/library/scala/util/continuations/package.scala
index e2fdc235ac..63547fa50a 100644
--- a/src/continuations/library/scala/util/continuations/package.scala
+++ b/src/continuations/library/scala/util/continuations/package.scala
@@ -56,7 +56,7 @@ package scala.util
* <h2>CPS Annotation</h2>
*
* The aforementioned `@cps[A]` annotation is an alias for the more general `@cpsParam[B,C]`
- * where `B=C`. The type `A @cps[B,C]` describes a term which yields a value of type `A` within
+ * where `B=C`. The type `A @cpsParam[B,C]` describes a term which yields a value of type `A` within
* an evaluation context producing a value of type `B`. After the CPS transformation, this return
* type is modified to `C`.
*
@@ -67,15 +67,60 @@ package scala.util
package object continuations {
+ /** An annotation that denotes a type is part of a continuation context.
+ * `@cps[A]` is shorthand for `cpsParam[A,A]`.
+ * @tparam A The return type of the continuation context.
+ */
type cps[A] = cpsParam[A,A]
+ /** 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]`.
+ */
type suspendable = cps[Unit]
-
+ /**
+ * 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.
+ *
+ * @param fun A function where
+ * - The parameter is the remainder of computation within the current
+ * `reset` block. This is passed as a function `A => B`.
+ * - The return is the return value of the `ControlContext` which is
+ * generated from this inversion.
+ * @note: 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.
+ */
def shift[A,B,C](fun: (A => B) => C): A @cpsParam[B,C] = {
throw new NoSuchMethodException("this code has to be compiled with the Scala continuations plugin enabled")
}
-
+ /** 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.
+ * @return The result of a block of code that uses `shift` to capture continuations.
+ */
def reset[A,C](ctx: =>(A @cpsParam[A,C])): C = {
val ctxR = reify[A,A,C](ctx)
if (ctxR.isTrivial)
@@ -102,10 +147,14 @@ package object continuations {
shiftUnit[A,B,B](x)
}
+
def shiftUnit[A,B,C>:B](x: A): A @cpsParam[B,C] = {
throw new NoSuchMethodException("this code has to be compiled with the Scala continuations plugin enabled")
}
+ /** 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.
+ */
def reify[A,B,C](ctx: =>(A @cpsParam[B,C])): ControlContext[A,B,C] = {
throw new NoSuchMethodException("this code has to be compiled with the Scala continuations plugin enabled")
}
@@ -113,7 +162,12 @@ package object continuations {
def shiftUnitR[A,B](x: A): ControlContext[A,B,B] = {
new ControlContext(null, x)
}
-
+ /**
+ * Captures a computation into a `ControlContext`.
+ * @param fun The function which accepts the inverted computation and returns
+ * a final result.
+ * @see shift
+ */
def shiftR[A,B,C](fun: (A => B) => C): ControlContext[A,B,C] = {
new ControlContext((f:A=>B,g:Exception=>B) => fun(f), null.asInstanceOf[A])
}