node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def...
Transcript of node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def...
![Page 1: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/1.jpg)
node.js?done.scala!Implementing Scalable Async IO using
Delimited Continuations
Tiark Rompf, EPFL
Saturday, June 4, 2011
![Page 2: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/2.jpg)
who has heard about node.js?
Saturday, June 4, 2011
![Page 3: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/3.jpg)
6/3/11 7:18 AMnode.js
Page 1 of 4http://nodejs.org/
Evented I/O for V8 JavaScript.
An example of a web server written in Node which responds with"Hello World" for every request.
var http = require('http');http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n');}).listen(1337, "127.0.0.1");console.log('Server running at http://127.0.0.1:1337/');
To run the server, put the code into a file example.js and executeit with the node program:
% node example.jsServer running at http://127.0.0.1:1337/
Here is an example of a simple TCP server which listens on port1337 and echoes whatever you send it:
var net = require('net');
var server = net.createServer(function (socket) { socket.write("Echo server\r\n"); socket.pipe(socket);});
DownloadChangeLogAboutv0.4.8 docs
WikiBlogCommunityDemoJobs
Hash InsightsChickRx
Saturday, June 4, 2011
![Page 4: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/4.jpg)
purely asynchronous
callback driven
no blocking operations
good scalability
Saturday, June 4, 2011
![Page 5: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/5.jpg)
6/3/11 7:22 AMGoogle Trends: erlang, node.js, clojure,
Page 1 of 1http://www.google.com/trends?q=erlang%2C+node.js%2C+clojure%2C&ctab=0&geo=all&date=all&sort=0
[email protected] | Signout
erlang, node.js, clojure,
Search Trends
Tip: Use commas to compare multiple search terms.
Searches Websites All regions All years
Scale is based on the average worldwide traffic of erlang in all years. Learn more
erlang 1.00 node.js 0.08 clojure 0.12
Rank by erlang
Scaling Large Projects With ErlangSlashdot - Jul 6 2008
The AZ of Programming Languages: ErlangComputerworld - Jun 16 2009
The AZ of Programming Languages: ClojureComputerworld - Aug 10 2009
Erlang Solutions, Ltd. and Basho Technologies, Inc. EnterBroad Partnership to Deliver Scalable, Fault TolerantApplications to a Global MarketCNNMoney.com - Mar 30 2010
Programming ClojureSlashdot - May 17 2010
Erlang and OTP in ActionSlashdot - Dec 8 2010
More news results »
Regions
1. Sweden
2. RussianFederation
3. SouthKorea
4. SouthAfrica
5. India
6. Singapore
7. Ukraine
8. Indonesia
9. China
10. Philippines
Cities
1. Goteborg,Sweden
2. Stockholm,Sweden
3.Moscow,RussianFederation
4. Beijing,China
5.SanFrancisco,CA, USA
6. Shanghai,China
7. Guangzhou,China
8. Seattle,WA, USA
9. Delhi, India
10. Bogota,Colombia
Languages
1. Swedish
2. Korean
3. Russian
4. Chinese
5. English
6. Indonesian
7. Danish
8. Hungarian
9. Japanese
10. German
Export this page as a CSV file
Google Trends provides insights into broad search patterns. Please keep in mind that several approximations areused when computing these results.
©2008 Google - Discuss - Terms of Use - Privacy Policy - Help
Saturday, June 4, 2011
![Page 6: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/6.jpg)
why would Scala programmers care?
Saturday, June 4, 2011
![Page 7: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/7.jpg)
#1: it’s about scalability
Saturday, June 4, 2011
![Page 8: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/8.jpg)
#2: no equivalent Scala libs
Saturday, June 4, 2011
![Page 9: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/9.jpg)
a little experiment: port it over to Scala!
Saturday, June 4, 2011
![Page 10: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/10.jpg)
done.scala
• a minimal scala port of node.js
• only net, http and supporting modules
• very incomplete (and not at all done!)
Saturday, June 4, 2011
![Page 11: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/11.jpg)
an interesting exercise:
JavaScript Scaladynamic language statically typed
Saturday, June 4, 2011
![Page 12: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/12.jpg)
• added type annotations in a few places
• helper classes for anonymous objects{ host: ‘google.com’, port: 80 }
• overloading, default arguments and varargs instead of dynamic typeof
quite smooth overall:
Saturday, June 4, 2011
![Page 13: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/13.jpg)
use Java NIO underneath
Saturday, June 4, 2011
![Page 14: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/14.jpg)
http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}) res.end('Hello World\n')}).listen(8000, "127.0.0.1")console.log('server running')
http.createServer { (req, res) => res.writeHead(200, "Content-Type" -> "text/plain") res.end("Hello World\n")}.listen(8000, "127.0.0.1")println("server running")
JavaScript
Scala
Saturday, June 4, 2011
![Page 15: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/15.jpg)
now what?
Saturday, June 4, 2011
![Page 16: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/16.jpg)
node’s conscious choice:only callback-driven apis
but is it the right choice?
Saturday, June 4, 2011
![Page 17: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/17.jpg)
small examples are fine but does it scale?
Saturday, June 4, 2011
![Page 18: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/18.jpg)
println(“hello”)setTimeout(1000) {
println(“world”)}
Saturday, June 4, 2011
![Page 19: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/19.jpg)
println(“hello”)setTimeout(1000) {
println(“world”)}
hello<pause>world
Saturday, June 4, 2011
![Page 20: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/20.jpg)
setTimeout(1000) {println(“world”)
}println(“hello”)
Saturday, June 4, 2011
![Page 21: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/21.jpg)
setTimeout(1000) {println(“world”)
}println(“hello”)
hello<pause>world
Saturday, June 4, 2011
![Page 22: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/22.jpg)
for (x <- List(1,2,3) {setTimeout(1000) {
println(“found ” + x)}
}
Saturday, June 4, 2011
![Page 23: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/23.jpg)
for (x <- List(1,2,3) {setTimeout(1000) {
println(“found ” + x)}
}
<pause>found 1found 2found 3
Saturday, June 4, 2011
![Page 24: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/24.jpg)
try {setTimeout(1000) {
throw new Exception}
} catch {case e =>
println(“caught: ” + e)}
Saturday, June 4, 2011
![Page 25: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/25.jpg)
try {setTimeout(1000) {
throw new Exception}
} catch {case e =>
println(“caught: ” + e)}
?Saturday, June 4, 2011
![Page 26: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/26.jpg)
many things no longer work as expected
Saturday, June 4, 2011
![Page 27: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/27.jpg)
callback-driven programmingis really hard
Saturday, June 4, 2011
![Page 28: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/28.jpg)
val host = “http://search.twitter.com/”val query = “#scaladays”
http.get(host,80,“search.atom?q=”+query) { res => println(“STATUS:” + res.statusCode) res.onData { chunk => println(“BODY:” + chunk) } res.onEnd { println(“DONE”) }}
Saturday, June 4, 2011
![Page 29: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/29.jpg)
val host = “http://search.twitter.com/”val query = “#scaladays”
http.get(host,80,“search.atom?q=”+query) { res => println(“STATUS:” + res.statusCode) res.onData { chunk => println(“BODY:” + chunk) } res.onEnd { println(“DONE”) }}
STATUS: 400BODY: <data>BODY: <more data>DONE
Saturday, June 4, 2011
![Page 30: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/30.jpg)
val host = “http://search.twitter.com/”val queries = List(“#scala”,“#scaladays”, “@odersky”)
val results = for (q <- queries) yield { http.get(host,80,“search.atom?q=”+query) { res => ... }}
println(results)
Saturday, June 4, 2011
![Page 31: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/31.jpg)
val host = “http://search.twitter.com/”val queries = List(“#scala”,“#scaladays”, “@odersky”)
val results = for (q <- queries) yield { http.get(host,80,“search.atom?q=”+query) { res => ... }}
println(results)
List(ClientRequest, ClientRequest, ClientRequest)
Saturday, June 4, 2011
![Page 32: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/32.jpg)
can we do something about it?
Saturday, June 4, 2011
![Page 33: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/33.jpg)
execute asynchronously
program synchronously
Saturday, June 4, 2011
![Page 34: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/34.jpg)
scalac -P:continuations:enable
Saturday, June 4, 2011
![Page 35: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/35.jpg)
def foobar: Int @suspendable = shift { retrn: (Int=>Unit) => retrn(7)}
def abort: Unit @suspendable = shift { retrn: (Unit=>Unit) => // just don’t return...
}
reset {println(“A”)abortprintln(“B”)
}println(“C”)
Saturday, June 4, 2011
![Page 36: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/36.jpg)
def foobar: Int @suspendable = shift { retrn: (Int=>Unit) => retrn(7)}
def abort: Unit @suspendable = shift { retrn: (Unit=>Unit) => // just don’t return...
}
reset {println(“A”)abortprintln(“B”)
}println(“C”)
AC
Saturday, June 4, 2011
![Page 37: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/37.jpg)
def setTimeout(delay: Int)(callback: => Unit): Unit = ...
println(“hello”)setTimeout(1000) {
println(“world”)}
Saturday, June 4, 2011
![Page 38: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/38.jpg)
def setTimeout(delay: Int)(callback: => Unit): Unit = ...
println(“hello”)setTimeout(1000) {
println(“world”)}
hello<pause>world
Saturday, June 4, 2011
![Page 39: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/39.jpg)
def setTimeout(delay: Int)(callback: => Unit): Unit = ...
def sleep(delay: Int) = shift { retrn: (Unit=>Unit) => setTimeout {
retrn()}
}
println(“hello”)setTimeout(1000) {
println(“world”)}
println(“hello”)sleep(1000)println(“world”)
hello<pause>world
Saturday, June 4, 2011
![Page 40: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/40.jpg)
def setTimeout(delay: Int)(callback: => Unit): Unit = ...
def sleep(delay: Int) = shift { retrn: (Unit=>Unit) => setTimeout {
retrn()}
}
println(“hello”)setTimeout(1000) {
println(“world”)}
println(“hello”)sleep(1000)println(“world”)
hello<pause>world
hello<pause>world
Saturday, June 4, 2011
![Page 41: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/41.jpg)
http.get(...) { res => res.onData { chunk => println(“BODY:” + chunk) } res.onEnd { println(“DONE”) }}
Saturday, June 4, 2011
![Page 42: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/42.jpg)
http.get(...) { res => res.onData { chunk => println(“BODY:” + chunk) } res.onEnd { println(“DONE”) }}
val res = http.get(...)
for (chunk <- res.data) { println(“BODY:” + chunk)}
println(“DONE”)
Saturday, June 4, 2011
![Page 43: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/43.jpg)
http.get(...) { res => res.onData { chunk => println(“BODY:” + chunk) } res.onEnd { println(“DONE”) }}
val res = http.get(...)
for (chunk <- res.data) { println(“BODY:” + chunk)}
println(“DONE”)
def data = new { def foreach(yld: Buffer=>Unit) = shift { retrn: (Unit=>Unit) =>
onData(yld)onEnd(retrn)
}def mkString = {
val s = new StringBuilder; foreach(s+=_); s.result}
}Saturday, June 4, 2011
![Page 44: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/44.jpg)
val host = “http://search.twitter.com/”val queries = List(“#scala”,“#scaladays”, “@odersky”)
val results = for (q <- queries) yield {val res = http.get(host,80,“search.atom?q=”+query)val xml = XML.loadString(res.data.mkString)xml \ "entry" \ "title" text
}
println(results)
Saturday, June 4, 2011
![Page 45: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/45.jpg)
val host = “http://search.twitter.com/”val queries = List(“#scala”,“#scaladays”, “@odersky”)
val results = for (q <- queries) yield {val res = http.get(host,80,“search.atom?q=”+query)val xml = XML.loadString(res.data.mkString)xml \ "entry" \ "title" text
}
println(results)
<console>:11: error: no type parameters for method map: (f: (java.lang.String) => B)(implicit bf: scala.collection.generic.CanBuildFrom[List[java.lang.String],B,That])That exist so that it can be applied to arguments ((java.lang.String) => String @scala.util.continuations.cpsParam[Unit,Unit])
Saturday, June 4, 2011
![Page 46: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/46.jpg)
val host = “http://search.twitter.com/”val queries = List(“#scala”,“#scaladays”, “@odersky”)
val results = for (q <- queries.suspendable) yield {val res = http.get(host,80,“search.atom?q=”+query)val xml = XML.loadString(res.data.mkString)xml \ "entry" \ "title" text
}
println(results)
Saturday, June 4, 2011
![Page 47: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/47.jpg)
val host = “http://search.twitter.com/”val queries = List(“#scala”,“#scaladays”, “@odersky”)
val results = for (q <- queries.suspendable) yield {val res = http.get(host,80,“search.atom?q=”+query)val xml = XML.loadString(res.data.mkString)xml \ "entry" \ "title" text
}
println(results)
List(List(“#Scala highlighted in article from @TheEconomist on parallel programing and multicore: http://econ.st/jkGchu @typesafe”, ...), List(“There are so many great talks today at #scaladays; it's hard to decide which to attend!”, ...), List(“@odersky is there any info on Cascade up somewhere?”, ...))
Saturday, June 4, 2011
![Page 48: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/48.jpg)
implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {
def foreach(yld: A => Unit @suspendable): Unit @suspendable = {val it = xs.iteratorwhile (it.hasNext) yld(it.next)
}def map[B, That](f: A => B @suspendable)
(implicit bf: CanBuildFrom[Repr, B, That]): That @suspendable = {val b = bf(xs.repr)foreach(x => b += f(x))b.result
}}
}
val results = for (q <- List(1,2,3).suspendable) yield {sleep(1000); println(“tick”)
}
Saturday, June 4, 2011
![Page 49: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/49.jpg)
implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {
def foreach(yld: A => Unit @suspendable): Unit @suspendable = {val it = xs.iteratorwhile (it.hasNext) yld(it.next)
}def map[B, That](f: A => B @suspendable)
(implicit bf: CanBuildFrom[Repr, B, That]): That @suspendable = {val b = bf(xs.repr)foreach(x => b += f(x))b.result
}}
}<pause>tick<pause>tick<pause>tick
val results = for (q <- List(1,2,3).suspendable) yield {sleep(1000); println(“tick”)
}
Saturday, June 4, 2011
![Page 50: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/50.jpg)
val host = “http://search.twitter.com/”val queries = List(“#scala”,“#scaladays”, “@odersky”)
val results = for (q <- queries.suspendable) yield {println(“start ”+q)val res = http.get(host,80,“search.atom?q=”+query)val xml = XML.loadString(res.data.mkString)println(“done ”+q)xml \ "entry" \ "title" text
}
Saturday, June 4, 2011
![Page 51: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/51.jpg)
val host = “http://search.twitter.com/”val queries = List(“#scala”,“#scaladays”, “@odersky”)
val results = for (q <- queries.suspendable) yield {println(“start ”+q)val res = http.get(host,80,“search.atom?q=”+query)val xml = XML.loadString(res.data.mkString)println(“done ”+q)xml \ "entry" \ "title" text
}
start #scaladone #scalastart #scaladaysdone #scaladaysstart @oderskydone @odersky
Saturday, June 4, 2011
![Page 52: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/52.jpg)
def spawn(body: => Unit @suspendable) = {eventLoop.submitTask(() => reset(body))
}
class DataFlowCell[A] {private[this] var value: Option[A] = Noneprivate[this] var queue: List[A=>Unit] = Nil
def apply() = shift { retrn: (A=>Unit) =>value match {
case Option(v) => retrn(v)case None => queue ::= retrn
}}
def set(v: A) = value match {case Option(_) => assert(false, “can’t set value twice”)case None => value = Some(v); queue.foreach(f => spawn(f(v)))
}}
Saturday, June 4, 2011
![Page 53: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/53.jpg)
def future[A](body: => A @suspendable) = {val cell = new DataFlowCell[A]spawn { cell.set(body) }cell
}
def par[A,B](a: => A @suspendable)(b: => B @suspendable) = {val (u,v) = (future(a), future(b))(u(),v())
}
par { sleep(1000); println(“a”)
} { sleep(1000); println(“b”)
}println(“done”)
Saturday, June 4, 2011
![Page 54: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/54.jpg)
def future[A](body: => A @suspendable) = {val cell = new DataFlowCell[A]spawn { cell.set(body) }cell
}
def par[A,B](a: => A @suspendable)(b: => B @suspendable) = {val (u,v) = (future(a), future(b))(u(),v())
}
par { sleep(1000); println(“a”)
} { sleep(1000); println(“b”)
}println(“done”)
<pause>badone
Saturday, June 4, 2011
![Page 55: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/55.jpg)
implicit def richParIterable[A,Seq,Repr](xs: ParIterableLike[A,Seq,Repr]) = new {def suspendable = new {
def foreach(yld: A => Unit @suspendable): Unit @suspendable = {val futures = xs.seq.map(x => future(yld(x)) // sequential list of futuresfutures.suspendable.foreach(_.apply())
}def map[B, That](f: A => B @suspendable)(... bf ...): That @suspendable = {
val futures = xs.seq.map(x => future(yld(x))futures.suspendable.map(_.apply())
}}
}
val results = for (q <- List(1,2,3).par.suspendable) yield {sleep(1000); println(“tick”)
}println(“done”)
Saturday, June 4, 2011
![Page 56: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/56.jpg)
implicit def richParIterable[A,Seq,Repr](xs: ParIterableLike[A,Seq,Repr]) = new {def suspendable = new {
def foreach(yld: A => Unit @suspendable): Unit @suspendable = {val futures = xs.seq.map(x => future(yld(x)) // sequential list of futuresfutures.suspendable.foreach(_.apply())
}def map[B, That](f: A => B @suspendable)(... bf ...): That @suspendable = {
val futures = xs.seq.map(x => future(yld(x))futures.suspendable.map(_.apply())
}}
}
<pause>tickticktickdone
val results = for (q <- List(1,2,3).par.suspendable) yield {sleep(1000); println(“tick”)
}println(“done”)
Saturday, June 4, 2011
![Page 57: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/57.jpg)
val host = “http://search.twitter.com/”val queries = List(“#scala”,“#scaladays”, “@odersky”)
val results = for (q <- queries.par.suspendable) yield {println(“start ”+q)val res = http.get(host,80,“search.atom?q=”+query)val xml = XML.loadString(res.data.mkString)println(“done ”+q)xml \ "entry" \ "title" text
}
Saturday, June 4, 2011
![Page 58: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/58.jpg)
val host = “http://search.twitter.com/”val queries = List(“#scala”,“#scaladays”, “@odersky”)
val results = for (q <- queries.par.suspendable) yield {println(“start ”+q)val res = http.get(host,80,“search.atom?q=”+query)val xml = XML.loadString(res.data.mkString)println(“done ”+q)xml \ "entry" \ "title" text
}
start #scalastart #scaladaysstart @oderskydone #scaladone #scaladaysdone @odersky
Saturday, June 4, 2011
![Page 59: node.js? done.scala!days2011.scala-lang.org/sites/days2011/files/56. node...implicit def richIterable[A,Repr](xs: IterableLike[A,Repr]) = new { def suspendable = new {def foreach(yld:](https://reader033.fdocuments.in/reader033/viewer/2022053002/5f061f477e708231d41666ba/html5/thumbnails/59.jpg)
Conclusions
• Scala needs good networking libs
• asynchronous execution does not meancallback-driven programming
• continuations can re-introduce synchronictiy
Saturday, June 4, 2011