Skip to content

Instantly share code, notes, and snippets.

@huynhjl
Created February 7, 2010 05:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save huynhjl/297230 to your computer and use it in GitHub Desktop.
Save huynhjl/297230 to your computer and use it in GitHub Desktop.
code with scalac -print output at the end
// The continuation code is from an answer by Rich posted at StackOverflow
// http://stackoverflow.com/questions/2201882/implementing-yield-yield-return-using-scala-continuations/2215182#2215182
import scala.continuations._
import scala.continuations.ControlContext.{shift,reset}
sealed trait Iteration[+R]
case class Yield[+R](result: R, next: () => Iteration[R]) extends Iteration[R]
case object Done extends Iteration[Nothing]
object YieldTest {
def trampoline[R](body: => Iteration[R]): Iterator[R] = {
def loop(thunk: () => Iteration[R]): Stream[R] = {
thunk.apply match {
case Yield(result, next) => Stream.cons(result, loop(next))
case Done => Stream.empty
}
}
loop(() => body).iterator
}
def iterator[R](body: => Unit @cps[Iteration[R],Iteration[R]]): Iterator[R] =
trampoline {
reset[Iteration[R],Iteration[R]] { body ; Done }
}
def yld[R](result: R): Unit @cps[Iteration[R],Iteration[R]] =
shift((k: Unit => Iteration[R]) => Yield(result, () => k(())))
def main(args:Array[String]): Unit = {
val itr2 = iterator[Int] {
yld(1)
yld(2)
yld(3)
}
for (i <- itr2) { println(i) }
}
}
/** OUTPUT of scalac -print *************************************/
[[syntax trees at end of cleanup]]// Scala source: Yield.scala
package <empty> {
sealed abstract trait Iteration extends java.lang.Object;
@serializable
case class Yield extends java.lang.Object with Iteration with ScalaObject with Product {
def productIterator(): Iterator = scala.Product$class.productIterator(Yield.this);
@deprecated("use productIterator instead")
def productElements(): Iterator = scala.Product$class.productElements(Yield.this);
<synthetic> def copy$default$2(): Function0 = Yield.this.next();
<synthetic> def copy$default$1(): java.lang.Object = Yield.this.result();
<caseaccessor> <paramaccessor> private[this] val result: java.lang.Object = _;
<stable> <caseaccessor> <accessor> <paramaccessor> def result(): java.lang.Object = Yield.this.result;
<caseaccessor> <paramaccessor> private[this] val next: Function0 = _;
<stable> <caseaccessor> <accessor> <paramaccessor> def next(): Function0 = Yield.this.next;
<synthetic> def copy(result: java.lang.Object = result, next: Function0 = next): Yield = new Yield(result, next);
override def hashCode(): Int = ScalaRunTime.this._hashCode(Yield.this);
override def toString(): java.lang.String = ScalaRunTime.this._toString(Yield.this);
override def equals(x$1: java.lang.Object): Boolean = Yield.this.eq(x$1).||({
{
var temp1: java.lang.Object = x$1;
if (temp1.$isInstanceOf[Yield]())
{
{
var temp2: Yield = temp1.$asInstanceOf[Yield]();
{
var temp3: java.lang.Object = temp2.result();
{
var temp4: Function0 = temp2.next();
{
{
val next$1: Function0 = temp4;
{
val result$1: java.lang.Object = temp3;
if (Yield.this.gd1$1(result$1, next$1))
{
{
val result$1: java.lang.Object = temp3;
{
{
x$1.$asInstanceOf[Yield]().canEqual(Yield.this)
}
}
}
}
else
{
false
}
}
}
}
}
}
}
}
else
{
false
}
}
});
override def productPrefix(): java.lang.String = "Yield";
override def productArity(): Int = 2;
override def productElement(x$1: Int): java.lang.Object = {
var temp5: Int = x$1;
(temp5: Int) match {
case 0 => {
Yield.this.result()
}
case 1 => {
Yield.this.next()
}
case _ => {
throw new java.lang.IndexOutOfBoundsException(scala.Int.box(x$1).toString())
}
}
};
override def canEqual(x$1: java.lang.Object): Boolean = x$1.$isInstanceOf[Yield]();
final <synthetic> private[this] def gd1$1(x$1: java.lang.Object, x$2: Function0): Boolean = x$1.==(Yield.this.result()).&&(x$2.==(Yield.this.next()));
def this(result: java.lang.Object, next: Function0): Yield = {
Yield.this.result = result;
Yield.this.next = next;
Yield.super.this();
scala.Product$class./*Product$class*/$init$(Yield.this);
()
}
};
@serializable
final case class Done extends java.lang.Object with Iteration with ScalaObject with Product {
def productIterator(): Iterator = scala.Product$class.productIterator(Done.this);
@deprecated("use productIterator instead")
def productElements(): Iterator = scala.Product$class.productElements(Done.this);
final override def toString(): java.lang.String = "Done";
override def productPrefix(): java.lang.String = "Done";
override def productArity(): Int = 0;
override def productElement(x$1: Int): java.lang.Object = {
var temp6: Int = x$1;
{
throw new java.lang.IndexOutOfBoundsException(scala.Int.box(x$1).toString())
}
};
override def canEqual(x$1: java.lang.Object): Boolean = x$1.$isInstanceOf[object Done]();
protected def readResolve(): java.lang.Object = Done;
def this(): object Done = {
Done.super.this();
scala.Product$class./*Product$class*/$init$(Done.this);
()
}
};
final class YieldTest extends java.lang.Object with ScalaObject {
def trampoline(body: Function0): Iterator = YieldTest.this.loop$1(body).iterator();
def iterator(body$1: Function0): Iterator = YieldTest.this.trampoline({
(new YieldTest$$anonfun$iterator$1(body$1): Function0)
});
def yld(result$2: java.lang.Object): scala.continuations.ControlContext = ControlContext.this.shiftR({
(new YieldTest$$anonfun$yld$1(result$2): Function1)
});
def main(args: Array[java.lang.String]): Unit = {
val itr2: Iterator = YieldTest.this.iterator({
(new YieldTest$$anonfun$1(): Function0)
});
itr2.foreach({
(new YieldTest$$anonfun$main$1(): Function1)
})
};
final def loop$1(thunk: Function0): scala.collection.immutable.Stream = {
val temp7: Iteration = thunk.apply().$asInstanceOf[Iteration]();
if (temp7.$isInstanceOf[Yield]())
{
{
var temp8: Yield = temp7.$asInstanceOf[Yield]();
{
var temp9: java.lang.Object = temp8.result();
{
var temp10: Function0 = temp8.next();
{
{
val result: java.lang.Object = temp9;
{
{
val next$2: Function0 = temp10;
scala.collection.immutable.Stream$cons.apply(result, {
(new YieldTest$$anonfun$loop$1$1(next$2): Function0)
})
}
}
}
}
}
}
}
}
else
if (Done.==(temp7))
{
{
{
scala.package.Stream().empty()
}
}
}
else
throw new MatchError(temp7.toString())
};
def this(): object YieldTest = {
YieldTest.super.this();
()
}
};
final <synthetic> class Yield extends java.lang.Object with ScalaObject {
case <synthetic> def unapply(x$0: Yield): Some = new Some(new Tuple2(x$0.result(), x$0.next()));
case <synthetic> def apply(result: java.lang.Object, next: Function0): Yield = new Yield(result, next);
def this(): object Yield = {
Yield.super.this();
()
}
};
@SerialVersionUID(0) @serializable
final <synthetic> class YieldTest$$anonfun$loop$1$1 extends scala.runtime.AbstractFunction0 {
final def apply(): scala.collection.immutable.Stream = YieldTest.loop$1(YieldTest$$anonfun$loop$1$1.this.next$2);
final <bridge> def apply(): java.lang.Object = YieldTest$$anonfun$loop$1$1.this.apply();
<synthetic> <paramaccessor> private[this] val next$2: Function0 = _;
def this(next$2: Function0): YieldTest$$anonfun$loop$1$1 = {
YieldTest$$anonfun$loop$1$1.this.next$2 = next$2;
YieldTest$$anonfun$loop$1$1.super.this();
()
}
};
@SerialVersionUID(0) @serializable
final <synthetic> class YieldTest$$anonfun$iterator$1$$anonfun$apply$1$$anonfun$apply$2 extends scala.runtime.AbstractFunction1 {
final def apply(tmp1: scala.runtime.BoxedUnit): object Done = {
tmp1;
Done
};
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = YieldTest$$anonfun$iterator$1$$anonfun$apply$1$$anonfun$apply$2.this.apply(v1.$asInstanceOf[scala.runtime.BoxedUnit]());
def this($outer: YieldTest$$anonfun$iterator$1$$anonfun$apply$1): YieldTest$$anonfun$iterator$1$$anonfun$apply$1$$anonfun$apply$2 = {
YieldTest$$anonfun$iterator$1$$anonfun$apply$1$$anonfun$apply$2.super.this();
()
}
};
@SerialVersionUID(0) @serializable
final <synthetic> class YieldTest$$anonfun$iterator$1$$anonfun$apply$1 extends scala.runtime.AbstractFunction0 {
final def apply(): scala.continuations.ControlContext = YieldTest$$anonfun$iterator$1$$anonfun$apply$1.this.$outer.body$1.apply().$asInstanceOf[scala.continuations.ControlContext]().map({
(new YieldTest$$anonfun$iterator$1$$anonfun$apply$1$$anonfun$apply$2(YieldTest$$anonfun$iterator$1$$anonfun$apply$1.this): Function1)
});
<synthetic> <paramaccessor> private[this] val $outer: YieldTest$$anonfun$iterator$1 = _;
final <bridge> def apply(): java.lang.Object = YieldTest$$anonfun$iterator$1$$anonfun$apply$1.this.apply();
def this($outer: YieldTest$$anonfun$iterator$1): YieldTest$$anonfun$iterator$1$$anonfun$apply$1 = {
if ($outer.eq(null))
throw new java.lang.NullPointerException()
else
YieldTest$$anonfun$iterator$1$$anonfun$apply$1.this.$outer = $outer;
YieldTest$$anonfun$iterator$1$$anonfun$apply$1.super.this();
()
}
};
@SerialVersionUID(0) @serializable
final <synthetic> class YieldTest$$anonfun$iterator$1 extends scala.runtime.AbstractFunction0 {
final def apply(): Iteration = scala.continuations.ControlContext.reset({
(new YieldTest$$anonfun$iterator$1$$anonfun$apply$1(YieldTest$$anonfun$iterator$1.this): Function0)
}).$asInstanceOf[Iteration]();
final <bridge> def apply(): java.lang.Object = YieldTest$$anonfun$iterator$1.this.apply();
<synthetic> <paramaccessor> val body$1: Function0 = _;
def this(body$1: Function0): YieldTest$$anonfun$iterator$1 = {
YieldTest$$anonfun$iterator$1.this.body$1 = body$1;
YieldTest$$anonfun$iterator$1.super.this();
()
}
};
@SerialVersionUID(0) @serializable
final <synthetic> class YieldTest$$anonfun$yld$1$$anonfun$apply$3 extends scala.runtime.AbstractFunction0 {
final def apply(): Iteration = YieldTest$$anonfun$yld$1$$anonfun$apply$3.this.k$1.apply(scala.runtime.BoxedUnit.UNIT).$asInstanceOf[Iteration]();
final <bridge> def apply(): java.lang.Object = YieldTest$$anonfun$yld$1$$anonfun$apply$3.this.apply();
<synthetic> <paramaccessor> private[this] val k$1: Function1 = _;
def this($outer: YieldTest$$anonfun$yld$1, k$1: Function1): YieldTest$$anonfun$yld$1$$anonfun$apply$3 = {
YieldTest$$anonfun$yld$1$$anonfun$apply$3.this.k$1 = k$1;
YieldTest$$anonfun$yld$1$$anonfun$apply$3.super.this();
()
}
};
@SerialVersionUID(0) @serializable
final <synthetic> class YieldTest$$anonfun$yld$1 extends scala.runtime.AbstractFunction1 {
final def apply(k$1: Function1): Yield = new Yield(YieldTest$$anonfun$yld$1.this.result$2, {
(new YieldTest$$anonfun$yld$1$$anonfun$apply$3(YieldTest$$anonfun$yld$1.this, k$1): Function0)
});
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = YieldTest$$anonfun$yld$1.this.apply(v1.$asInstanceOf[Function1]());
<synthetic> <paramaccessor> private[this] val result$2: java.lang.Object = _;
def this(result$2: java.lang.Object): YieldTest$$anonfun$yld$1 = {
YieldTest$$anonfun$yld$1.this.result$2 = result$2;
YieldTest$$anonfun$yld$1.super.this();
()
}
};
@SerialVersionUID(0) @serializable
final <synthetic> class YieldTest$$anonfun$1$$anonfun$apply$4$$anonfun$apply$5 extends scala.runtime.AbstractFunction1 {
final def apply(tmp3: scala.runtime.BoxedUnit): scala.continuations.ControlContext = {
tmp3;
YieldTest.this.yld(scala.Int.box(3))
};
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = YieldTest$$anonfun$1$$anonfun$apply$4$$anonfun$apply$5.this.apply(v1.$asInstanceOf[scala.runtime.BoxedUnit]());
def this($outer: YieldTest$$anonfun$1$$anonfun$apply$4): YieldTest$$anonfun$1$$anonfun$apply$4$$anonfun$apply$5 = {
YieldTest$$anonfun$1$$anonfun$apply$4$$anonfun$apply$5.super.this();
()
}
};
@SerialVersionUID(0) @serializable
final <synthetic> class YieldTest$$anonfun$1$$anonfun$apply$4 extends scala.runtime.AbstractFunction1 {
final def apply(tmp2: scala.runtime.BoxedUnit): scala.continuations.ControlContext = {
tmp2;
YieldTest.this.yld(scala.Int.box(2)).flatMap({
(new YieldTest$$anonfun$1$$anonfun$apply$4$$anonfun$apply$5(YieldTest$$anonfun$1$$anonfun$apply$4.this): Function1)
})
};
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = YieldTest$$anonfun$1$$anonfun$apply$4.this.apply(v1.$asInstanceOf[scala.runtime.BoxedUnit]());
def this($outer: YieldTest$$anonfun$1): YieldTest$$anonfun$1$$anonfun$apply$4 = {
YieldTest$$anonfun$1$$anonfun$apply$4.super.this();
()
}
};
@SerialVersionUID(0) @serializable
final <synthetic> class YieldTest$$anonfun$1 extends scala.runtime.AbstractFunction0 {
final def apply(): scala.continuations.ControlContext = YieldTest.this.yld(scala.Int.box(1)).flatMap({
(new YieldTest$$anonfun$1$$anonfun$apply$4(YieldTest$$anonfun$1.this): Function1)
});
final <bridge> def apply(): java.lang.Object = YieldTest$$anonfun$1.this.apply();
def this(): YieldTest$$anonfun$1 = {
YieldTest$$anonfun$1.super.this();
()
}
};
@SerialVersionUID(0) @serializable
final <synthetic> class YieldTest$$anonfun$main$1 extends scala.runtime.AbstractFunction1 {
final def apply(i: Int): Unit = scala.this.Predef.println(scala.Int.box(i));
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = {
YieldTest$$anonfun$main$1.this.apply(scala.Int.unbox(v1));
scala.runtime.BoxedUnit.UNIT
};
def this(): YieldTest$$anonfun$main$1 = {
YieldTest$$anonfun$main$1.super.this();
()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment