17. var fib = function () {
var state = 0, last0, last1;
return {
moveNext: function () {
if (state == 0) { //
this.current = 0;
state = 1;
} else if (state == 1) { //
this.current = 1; var iter = fib();
last1 = 0; while (iter.moveNext()) {
state = 2; print(iter.current);
} else { }
last0 = last1;
last1 = this.current;
this.current = last0 + last1;
}
return true;
}
}
}
18. JavaScript 1.7*
function fibonacci() {
yield 0;
yield 1;
var a = 0, current = 1;
while (true) { for (var i in fibonacci()) {
var b = a; print(i);
a = current; }
current = a + b;
yield current;
}
}
* Firefox 2.0+ only: https://developer.mozilla.org/en/JavaScript/Guide/Iterators_and_Generators
20. 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);
}
}
}
}
21. 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();
}
}
22. 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();
}
}
34. 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://files.zhaojie.me/jscex/samples/async/sorting-animations.html?bubble
35. 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://files.zhaojie.me/jscex/samples/async/sorting-animations.html?bubble
38. function () {
var res = $await(<async work>);
}
HTTP
UI
Web Service
39. var f = eval(Jscex.compile("async", function () {
var img = $await(readAsync("http://..."));
console.log("loaded!");
$await(writeAsync("./files/..."));
console.log("saved!");
}));
40. …
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();
});
});
})
);
})');
41. …
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();
});
});
})
);
});
42. Express
var app = express.createServer();
app.get('/', function (req, res) {
/**
*
*
* 1.
* 2.
*
* 3. res
*
* “ ”
**/
});
app.listen(3000);
43. Jscex
app.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));
})));
44. Jscex vs.
•
•
• Virtual Panel: How to Survive Asynchronous
Programming in JavaScript
•
• StratifiedJS
• Narrative JavaScript
• Streamline Jscex
48. 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, _);
}
}
}
49. 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
50. 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));
}
}
}));
51. 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
);
})
);
})
52. 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
);
})
);
})
56. ... the principle we go by is, don't expect to see
a particular concurrency model put into C#
because there're many different concurrency
model ... it's more about finding things are
common to all kinds of concurrency ...
- Anders Hejlsberg
59. //
var fib = eval(Jscex.compile("seq", function () {
$yield(0);
$yield(1);
var a = 0, current = 1;
while (true) {
var b = a;
a = current;
current = a + b;
$yield(current);
}
}));
https://github.com/JeffreyZhao/jscex/blob/master/samples/seq/fib.html
61. var filter = eval(Jscex.compile("seq", function (iter, predicate) {
while (iter.moveNext()) {
if (predicate(iter.current)) {
$yield(iter.current);
}
}
}));
var map = eval(Jscex.compile("seq", function (iter, mapper) {
while (iter.moveNext()) {
$yield(mapper(iter.current));
}
}));
var zip = eval(Jscex.compile("seq", function (iter1, iter2) {
while (iter1.moveNext() && iter2.moveNext()) {
$yield([iter1.current, iter2.current]);
}
}));
https://github.com/JeffreyZhao/jscex/blob/master/src/jscex.seq.powerpack.js
62. Maybe Monad
var maybeFunc = function () {
var maybeA = getA();
if (maybeA != Maybe.None) {
var maybeB = getB();
if (maybeB != Maybe.None) {
return maybeA.value + maybeB.value;
} else {
return Maybe.None;
}
} else {
return Maybe.None;
}
}
//
var maybeFunc = eval(Jscex.compile("maybe", function () {
var a = $try(getA());
var b = $try(getB());
return a + b;
}));