From bfeef8a9d3015f1273dcda653fe4c20fdbc3f906 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Sun, 18 Sep 2011 13:28:55 +0000 Subject: Scaladoc enhancements to continuations package ... Scaladoc enhancements to continuations package for docspree. Review by rompf --- .../scala/util/continuations/ControlContext.scala | 87 +++++++++++++++++++++- .../library/scala/util/continuations/package.scala | 62 ++++++++++++++- 2 files changed, 142 insertions(+), 7 deletions(-) (limited to 'src/continuations/library') 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 *

CPS Annotation

* * 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]) } -- cgit v1.2.3