Upcoming SlideShare
×

# 深入浅出Jscex

4,150 views

Published on

4 Likes
Statistics
Notes
• Full Name
Comment goes here.

Are you sure you want to Yes No
• Be the first to comment

Views
Total views
4,150
On SlideShare
0
From Embeds
0
Number of Embeds
419
Actions
Shares
0
89
0
Likes
4
Embeds 0
No embeds

No notes for slide

### 深入浅出Jscex

1. 1. Jscex- 2011.10
2. 2. • / / Jeffrey Zhao /•• http://blog.zhaojie.me/• @• F#, JavaScript, Scala, C#, Python, .NET, Mono...• Java
3. 3. Jscex• JavaScript Computation EXpression• JavaScript• F# JavaScript • “ ” • JavaScript JavaScript
4. 4. Jscex• • Jscex JavaScript• • Jscex /• JavaScript / • ECMAScript 3
5. 5. var compare = function (x, y) { return x - y;}var swap = function (a, i, j) { var t = a[i]; a[i] = a[j]; a[j] = t;}var bubbleSort = function (array) { for (var x = 0; x < array.length; x++) { for (var y = 0; y < array.length - x; y++) { if (compare(array[y], array[y + 1]) > 0) { swap(array, y, y + 1); } } }}
6. 6. var compare = function (x, y, callback) { var innerLoop = function (array, x, y, callback) { setTimeout(10, function () { if (y < array.length - x) { callback(x - y); compare(array[y], array[y + 1], function (r) { }); if (r > 0) {} swap(array, y, y + 1, function () { innerLoop(array, x, y + 1, callback);var swap = function (a, i, j, callback) { }); var t = a[i]; a[i] = a[j]; a[j] = t; } else { repaint(a); innerLoop(array, x, y + 1, callback); } setTimeout(20, callback); });} } else { callback();var outerLoop = function (array, x, callback) { } if (x < array) { } innerLoop(array, x, 0, function () { outerLoop(array, x + 1, callback); outerLoop(array, 0, function () { }); console.log("done!"); } else { }); callback(); }}
7. 7. var compare = function (x, y, callback) { var innerLoop = function (array, x, y, callback) { setTimeout(10, function () { if (y < array.length - x) { callback(x - y); compare(array[y], array[y + 1], function (r) { }); if (r > 0) {} swap(array, y, y + 1, function () { innerLoop(array, x, y + 1, callback);var swap = function (a, i, j, callback) { }); var t = a[i]; a[i] = a[j]; a[j] = t; } else { D repaint(a); innerLoop(array, x, y + 1, callback); } M setTimeout(20, callback); });} } else { T callback();var outerLoop = function (array, x, callback) { } if (x < array) { } innerLoop(array, x, 0, function () { outerLoop(array, x + 1, callback); outerLoop(array, 0, function () { }); console.log("done!"); } else { }); callback(); }}
8. 8. var compareAsync = eval(Jscex.compile("async", function (x, y) { \$await(Jscex.Async.sleep(10)); // each "compare" takes 10 ms. return x - y;}));var swapAsync = eval(Jscex.compile("async", function (a, i, j) { var t = a[i]; a[i] = a[j]; a[j] = t; // swap repaint(a); // repaint after each swap \$await(Jscex.Async.sleep(20)); // each "swap" takes 20 ms.}));var bubbleSortAsync = eval(Jscex.compile("async", function (array) { for (var x = 0; x < array.length; x++) { for (var y = 0; y < array.length - x; y++) { var r = \$await(compareAsync(array[y], array[y + 1])); if (r > 0) \$await(swapAsync(array, y, y + 1)); } }})); http://ﬁles.zhaojie.me/jscex/samples/async/sorting-animations.html?bubble
9. 9. var compareAsync = eval(Jscex.compile("async", function (x, y) { \$await(Jscex.Async.sleep(10)); // each "compare" takes 10 ms. return x - y;}));var swapAsync = eval(Jscex.compile("async", function (a, i, j) { var t = a[i]; a[i] = a[j]; a[j] = t; // swap repaint(a); // repaint after each swap \$await(Jscex.Async.sleep(20)); // each "swap" takes 20 ms.}));var bubbleSortAsync = eval(Jscex.compile("async", function (array) { for (var x = 0; x < array.length; x++) { for (var y = 0; y < array.length - x; y++) { var r = \$await(compareAsync(array[y], array[y + 1])); if (r > 0) \$await(swapAsync(array, y, y + 1)); } }}));
10. 10. • • •• • •
11. 11. Jscex//var somethingAsync = eval(Jscex.compile("async", function (...) { // }));
12. 12. function () { var res = \$await(<async work>);}
13. 13. function () { var res = \$await(<async work>);} HTTP UI Web Service
14. 14. var f = eval(Jscex.compile("async", function () { var img = \$await(readAsync("http://...")); console.log("loaded!"); \$await(writeAsync("./files/...")); console.log("saved!");}));
15. 15. …var f = eval((function () { var _b_ = Jscex.builders["async"]; return _b_.Start(this, _b_.Delay(function () { _b_.Bind(readAsync(...), function (img) { console.log("loaded!"); return _b_.Bind(writeAsync(...), function () { console.log("saved!"); return _b_.Normal(); }); }); }) );}));
16. 16. …var f = (function () { var _b_ = Jscex.builders["async"]; return _b_.Start(this, _b_.Delay(function () { _b_.Bind(readAsync(...), function (img) { console.log("loaded!"); return _b_.Bind(writeAsync(...), function () { console.log("saved!"); return _b_.Normal(); }); }); }) );});
17. 17. Expressvar app = express.createServer();app.get(/, function (req, res) { /** * * * 1. * 2. * * 3. res * * “ ” **/});app.listen(3000);
18. 18. Jscexapp.getAsync(/, eval(Jscex.compile("async", function (req, res) { var keys = \$await(db.getKeysAsync(...)); var results = []; for (var i = 0; i < keys.length; i++) { var r = \$await(cache.getAsync(keys[i])); if (!r) { r = \$await(db.getItemAsync(keys[i])); } results.push(r); } res.send(generateList(results));})));
19. 19. I/O• I/O • Web ••• I/O •
20. 20. var getItemAsync = eval(Jscex.compile("async", function (key) { var res = \$await(cache.getAsync(key)); if (res) return res; return \$await(db.getItemAsync(key));}));app.getAsync(/, eval(Jscex.compile("async", function (req, res) { var keys = \$await(db.getKeysAsync(...)); // “ ” var tasks = keys.map(function (key) { return getItemAsync(key); }); // var results = \$await(Jscex.Async.parallel(tasks)); res.send(generateList(results));})));
22. 22. //var i = 1;conn.onAsync("data", eval(Jscex.compile("async", function () { var id = i++; \$await(step1); console.log("step 1 - request " + id); \$await(step2); console.log("step 2 - request " + id); /** * * step 1 - request 1 * step 1 - request 2 * step 2 - request 2 * step 2 - request 1 **/})));
23. 23. ... the principle we go by is, dont expect to seea particular concurrency model put into C#because therere many different concurrencymodel ... its more about ﬁnding things arecommon to all kinds of concurrency ... - Anders Hejlsberg
24. 24. Erlangvar i = 0;var agent = Agent.start(eval(Jscex.compile("async", function (mailbox) { while (true) { var id = i++; var msg = \$await(mailbox.receive()); \$await(step1); console.log("step 1 - request " + id); \$await(step2); console.log("step 2 - request " + id); }})));conn.on("data", function (data) { // mailbox agent.send(data);});
25. 25. Jscex• JavaScript • • •• “ ”
26. 26. • JavaScript • while / for / for...in / do • if / switch • try...catch...ﬁnally • return / break / continue / throw• • with • break continue • switch break•
27. 27. //var somethingAsync = eval(Jscex.compile("async", function (...) { // }));
28. 28. evalSample = { // compile: function (func) { return "(" + func.toString() + ")"; }, // eval compileEx: function (func) { return eval("(" + func.toString() + ")"); }}
29. 29. eval(function () { var a = 1; // f1 var f1 = eval(Sample.compile(function () { alert(a); })); f1(); // “1” // f2 Sample.compileEx var f2 = Sample.compileEx(function () { alert(a); }); f2(); // “a ”})();
30. 30. • JavaScript• “bind” \$await • • “ ” • “ ”
31. 31. • JavaScript•• • JIT • JavaScript
32. 32. “ ”MyClass.prototype = { get: function (n) { ... }, calculateAsync: eval(Jscex.compile("async", function (n) { var numbers = []; for (var i = 0; i < n; i++) numbers.push(i); this.result = \$await(make(numbers)); }))}
33. 33. “ ”MyClass.prototype = { get: function (n) { ... }, Jscex calculateAsync: eval(Jscex.compile("async", function (n) { var numbers = []; for (var i = 0; i < n; i++) numbers.push(i); this.result = \$await(make(numbers)); }))} Jscex
34. 34. Jscex vs.•• • Virtual Panel: How to Survive Asynchronous Programming in JavaScript• • StratiﬁedJS • Narrative JavaScript • Streamline Jscex
35. 35. Jscex vs.• • • •• Jscex • JavaScript • •
36. 36. Jscex vs.• • • •• Jscex • JavaScript • JavaScript • JavaScript
37. 37. Streamline• Jscex • JavaScript • JIT •• Jscex • • Yield – Resume vs. Asynchronous Callbacks – An Equivalence
38. 38. Streamline (input)var bubbleSortAsync = function (array, _) { for (var x = 0; x < array.length; x++) { for (var y = 0; y < array.length - x; y++) { if (compareAsync(array[y], array[y + 1], _) > 0) swapAsync(array, y, y + 1, _); } }}
39. 39. Streamline (compiled)var bubbleSortAsync = function __1(array, _) { if (!_) { return __future(__1, arguments, 1); } if ((y < (array.length - x))) {; return compareAsync(array[y], array[(y + 1)], __cb(_, function(__0, r) { var __then = _; if ((r > 0)) { var x = 0; return swapAsync(array, y, (y + 1), __cb(_, __then)); var __4 = false; } return function(__break) { ; var __loop = __nt(_, function() { return __then(); var __then = __loop; })); if (__4) { } x++; else { } return __break(); else { } __4 = true; ; } }); ; return __loop(); if ((x < array.length)) { }(__then); var y = 0; } var __3 = false; else { return function(__break) { return __break(); var __loop = __nt(_, function() { } var __then = __loop; ; if (__3) { }); y++; return __loop(); } }(__then); else { }; __3 = true; } ; http://sage.github.com/streamlinejs/examples/streamlineMe.html
40. 40. Jecex (input)var bubbleSortAsync = eval(Jscex.compile("async", function (array) { for (var x = 0; x < array.length; x++) { for (var y = 0; y < array.length - x; y++) { var r = \$await(compareAsync(array[y], array[y + 1])); if (r > 0) \$await(swapAsync(array, y, y + 1)); } }}));
41. 41. Jecex (compiled)var bubbleSortAsync = (function (array) { var _b_ = Jscex.builders["async"]; return _b_.Start(this, _b_.Delay(function () { var x = 0; return _b_.Loop( function () { return x < array.length; }, function () { x++; }, _b_.Delay(function () { var y = 0; return _b_.Loop( function () { return y < (array.length - x); }, function () { y++; } _b_.Delay(function () { return _b_.Bind(compareAsync(array[y], array[y + 1]), function (r) { if (r > 0) { return _b_.Bind(swapAsync(array, y, y + 1), function () { return _b_.Normal(); }); } else { return _b_.Normal(); } }); }), false ); }), false ); }) );})
42. 42. Jecex (compiled) var bubbleSortAsync = (function (array) { var _b_ = Jscex.builders["async"]; return _b_.Start(this, _b_.Delay(function () { outer loop var x = 0; return _b_.Loop( function () { return x < array.length; }, function () { x++; }, _b_.Delay(function () { var y = 0; return _b_.Loop( inner loop function () { return y < (array.length - x); }, function () { y++; } _b_.Delay(function () { return _b_.Bind(compareAsync(array[y], array[y + 1]), function (r) { if (r > 0) { return _b_.Bind(swapAsync(array, y, y + 1), function () {\$await(compareAsync(...)) return _b_.Normal(); }); } else { \$await(swapAsync(...)) return _b_.Normal(); } }); }), false ); }), false ); }) ); })
43. 43. Jscex• • • “debugger”• JavaScript • Start, Delay, Combine • Loop, Try • Normal, Return, Break, Continue, Throw • Bind
44. 44. Node.js
45. 45. • • JIT • AOT• • • Python C# JavaScript 1.7 • …
46. 46. AOT// AOTAgent.start(eval(Jscex.compile("async", function (mailbox) { ...})));// AOT//// gzip 3kbAgent.start((function (mailbox) { var _b_ = Jscex.builders["async"]; return _b_.Start(this, ... );}));
47. 47. Jscex• • “ ”•
48. 48. //var fib = eval(Jscex.compile("seq", function () { var i = 0, j = 1; while (true) { \$yield(i); // the bind operation var t = i; i = j; j += t; }}));var iter = fib().skip(10).take(10);while (iter.moveNext()) { console.log(iter.current);}
49. 49. … Maybe Monadvar maybeFunc = function () { var maybeA = getA(); if (maybeA == Maybe.None) return Maybe.None; var maybeB = getB(); if (maybeB == Maybe.None) return Maybe.None; return maybeA.value + maybeB.value;}//var maybeFunc = eval(Jscex.compile("maybe", function () { var a = \$try(getA()); var b = \$try(getB()); return a + b;}));
50. 50. • “ ” “ ” • •• • Jscex /
51. 51. for Loopfunction (urls) { for (var i = 0; i < urls.length; i++) { \$await(requestAsync(urls[i])); }}
52. 52. for Loopfunction (urls) { for (var i = 0; i < urls.length; i++) { \$await(requestAsync(urls[i])); }} function (urls) { var _b_ = Jscex.builders["async"]; return _b_.Start(this, _b_.Delay(function () { var i = 0; return _b_.Loop( function () { return i < urls.length; }, function () { i++; }, _b_.Delay(function () { return _b_.Bind(requestAsync(urls[i]), function () { return _b_.Normal(); }); }), false ); }) ); }
53. 53. forfunction (urls) { var requests = []; for (var i = 0; i < urls.length; i++) { requests.push(requestAsync(urls[i])); } \$await(Jscex.Async.parallel(requests));}
54. 54. forfunction (urls) { var requests = []; for (var i = 0; i < urls.length; i++) { requests.push(requestAsync(urls[i])); } function (urls) { var _b_ = Jscex.builders["async"]; \$await(Jscex.Async.parallel(requests));} return _b_.Start(this, _b_.Delay(function () { var requests = []; for (var i = 0; i < urls.length; i++) { requests.push(requestAsync(urls[i])); } return _b_.Bind(Jscex.Async.parallel(requests), function () { return _b_.Normal(); }); }) ); }
55. 55. • BSD• • https://github.com/JeffreyZhao/jscex • http://www.sndacode.com/projects/jscex
56. 56. Q &A