Skip to content

Instantly share code, notes, and snippets.

@yllan
Last active December 15, 2015 16:49
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yllan/5291532 to your computer and use it in GitHub Desktop.
Save yllan/5291532 to your computer and use it in GitHub Desktop.
Rewrite the Go tutorial of goroutine with scala.concurrent.
// Rewrite http://tour.golang.org/#63 to scala using Channel
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
object GO63Channel extends App {
def sum(a: List[Int], c: Channel[Int]) = future {
c write a.sum
}
val c = new Channel[Int]()
val a = List(7, 2, 8, -9, 4, 0)
sum(a.take(a.length / 2), c)
sum(a.drop(a.length / 2), c)
val (x, y) = (c.read, c.read)
println(s"$x, $y, ${x + y}")
}
// Rewrite http://tour.golang.org/#63 to scala using Promise and Future.
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import java.util.concurrent.TimeUnit._
object GO63FuturePromise extends App {
def sum(a: List[Int], p: Promise[Int]) = future {
p success a.sum
}
val p1 = Promise[Int]
val p2 = Promise[Int]
val a = List(7, 2, 8, -9, 4, 0)
sum(a.take(a.length / 2), p1)
sum(a.drop(a.length / 2), p2)
val (x, y) = Await.result((p1.future zip p2.future), 10 seconds)
println(s"$x, $y, ${x + y}")
}
// Rewrite http://tour.golang.org/#65 by using None to signal the close of channel.
// It is easy to make a "ClosableChannel" class by wrapping the Channel with Option.
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
object GO65 extends App {
def fibonacci(n: Int, c: Channel[Option[Int]]) = future {
def fibIter(i: Int, x: Int, y: Int): Unit =
if (i >= n) {
c.write(None)
} else {
c.write(Some(x))
fibIter(i + 1, y, x + y)
}
fibIter(i = 0, x = 0, y = 1)
}
val c = new Channel[Option[Int]]()
fibonacci(20, c)
def looper(): Unit = c.read match {
case Some(x) => {
println(x)
looper
}
case None => {}
}
looper
}
// Rewrite http://tour.golang.org/#66 using Future.firstCompletedOf to simulate the select
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import java.util.concurrent.TimeUnit._
object GO66 extends App {
def fibonacci(c: SyncChannel[Int], q: Future[Int]) = {
def fibIter(x: Int, y: Int): Unit = {
val firstResult = Future.firstCompletedOf(List(future { c.write(x); c }, q))
Await.result(firstResult, 10 seconds) match {
case `c` => fibIter(y, x + y)
case i => println("quit")
}
}
fibIter(x = 0, y = 1)
}
val c = new SyncChannel[Int]()
val q = Promise[Int]
future {
(1 to 10) foreach { i =>
println(c.read)
}
q success 0
}
fibonacci(c, q.future)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment