@@ -21,32 +21,43 @@ object Test {
2121 }
2222 }
2323
24- /** * Producer represents a linear production of values.
24+ /** * Producer represents a linear production of values with a loop structure .
2525 *
2626 * Conceptually the design of the producer has its roots in `unfold` where a stream is a product type of some state
27- * and a stepper function. The latter transforms the state and returns either the end-of-the-stream or a value and
27+ * and a stepper function:
28+ *
29+ * {{
30+ * trait Stream[+A]
31+ * case class Unfold[S, +A](state: S, step: (S) => Option[(S, A)]) extends Stream[+A]
32+ * }}
33+ *
34+ * The latter transforms the state and returns either the end-of-the-stream or a value and
2835 * the new state. The existential quantification over the state keeps it private: the only permissible operation is
29- * to pass it to the step function .
36+ * to pass it to the function. However in `Producer` the elements are not pulled but the step accepts a continuation .
3037 *
31- * @tparam A type of the collection elements
38+ * A Producer defines the three basic elements of a loop structure:
39+ * - `init` contributes the code before iteration starts
40+ * - `step` contributes the code during execution
41+ * - `hasNext` contributes the code of the boolean test to end the iteration
42+ *
43+ * @tparam A type of the collection element. Since a `Producer` is polymorphic yet it handles `Expr` values, we
44+ * can pack together fragments of code to accompany each element production (e.g., a variable incremented
45+ * during each transformation)
3246 */
3347 trait Producer [A ] { self =>
3448 type St
3549 val card : Cardinality
3650
3751 /** Initialization method that defines new state, if needed by the combinator that this producer defines.
38- *
39- * e.g., `addCounter` which adds a counter
4052 *
4153 * @param k the continuation that is invoked after the new state is defined in the body of `init`
4254 * @return expr value of unit per the CPS-encoding
4355 */
4456 def init (k : St => Expr [Unit ]): Expr [Unit ]
4557
46- /** Step method that defines the transformation of data, if applicable .
58+ /** Step method that defines the transformation of data.
4759 *
48- *
49- * @param st
60+ * @param st the state needed for this iteration step
5061 * @param k
5162 * @return
5263 */
@@ -111,10 +122,10 @@ object Test {
111122
112123 /** Handles generically the mapping of elements from one producer to another.
113124 * `mapRaw` can be potentially used threading quoted values from one stream to another. However
114- * is can be also used by handling any kind of quoted value .
125+ * is can be also used by declaring any kind of computation we need to perform during each step .
115126 *
116127 * e.g., `mapRaw[(Var[Int], A), A]` transforms a stream that declares a variable and holds a value in each
117- * iteration step to a stream that is not aware of the aforementioned variable.
128+ * iteration step, to a stream that is not aware of the aforementioned variable.
118129 *
119130 * @param f the function to apply at each step. f is of type `(A => (B => Expr[Unit])` where A is the type of
120131 * the incoming stream. When applied to an element, `f` returns the continuation for elements of `B`
@@ -337,7 +348,12 @@ object Test {
337348 }
338349 }
339350
340- /**
351+ /** Make a stream linear
352+ *
353+ * Performs reification of the `stream`. It converts it to a function that will, when called, produce the current element
354+ * and advance the stream -- or report the end-of-stream.
355+ * The reified stream is an imperative *non-recursive* function, called `adv`, of `Unit => Unit` type. Nested streams are
356+ * also handled.
341357 *
342358 * @param stream
343359 * @tparam A
@@ -369,6 +385,10 @@ object Test {
369385 if (~ producer.hasNext(st)) {
370386 ~ producer.step(st, k)
371387 }
388+ else {
389+ val newAdvance = ~ currentAdvance.get
390+ newAdvance(_)
391+ }
372392 })
373393 case Many => producer.init(st => ' {
374394 val oldAdvance : Unit => Unit = ~ currentAdvance.get
0 commit comments