Permalink
Browse files

push this live to github, some progress....

  • Loading branch information...
1 parent 403288a commit 92c9299ef4e44830cb0b9057162dbd5a8a7546e8 @maxtaco committed Jan 9, 2012
@@ -0,0 +1,6 @@
+dns = require 'dns' # Use node.js's DNS resolution system
+for host in [ 'yahoo.com', 'google.com', 'nytimes.com']
+ await dns.resolve host, "A", defer err, ip
+ if err then console.log "Error for #{host}: #{err}"
+ else console.log "Resolved #{host} -> #{ip}"
+
@@ -0,0 +1,5 @@
+window.add = (a,b,cb) ->
+ await setTimeout defer(), 10
+ cb(a+b)
+x = (await add 3, 4, defer _) + (await add 1, 2, defer _)
+alert "#{x} is 10"
@@ -0,0 +1 @@
+x = await add (await add 1, 2, defer _), (await add 3, 4, defer _), defer _
@@ -0,0 +1,3 @@
+await add 1, 2, defer l
+await add 3, 4, defer r
+await add l, r, defer x
@@ -0,0 +1,5 @@
+for i in [0..2]
+ await
+ slowAlert 100, "fast alert #{i}", defer()
+ slowAlert 200, "slow alert #{i}", defer()
+
@@ -48,7 +48,9 @@
<a href="#installation">Installation</a>
<a href="#usage">Usage</a>
<a href="#language">Language Reference</a>
- <a href="#tame">Tame Features</a>
+ <a href="#tame">Tame Basic Features</a>
+ <a href="#tame_defer">Tame Defer Values</a>
+ <a href="#tame_expr">Tame Expressions</a>
<a href="#literals">Literals: Functions, Objects and Arrays</a>
<a href="#lexical_scope">Lexical Scoping and Variable Safety</a>
<a href="#conditionals">If, Else, Unless, and Conditional Assignment</a>
@@ -454,7 +456,71 @@ Here is simple example that waits for 1 second, and then calls <tt>alert</tt>:
<p>
<%= code_for('tame_loops_2', true) %>
</p>
+
+ Things start to get interesting when you combine parallel and
+ serial control flow, but the syntax remains the same:
+
+ <p>
+ <%= code_for('tame_loops_3', true) %>
+ </p>
+
+ <p>
+ <span id ="tame_defer" class = "bookmark"></span>
+ <b class="header">Tame Defer Values</b>
+ Many JS and coffee libraries use callbacks passed as parameters
+ to signify when the given operation has completed, and which values
+ were produced. As such, <tt>defer</tt> can take one or more arguments
+ which are filled in after a deferral is fulfilled. Note that the
+ snippet below is <i>node.js</i> code that requires a DNS resolver:
+ <p>
+ <%= code_for('tame_defer') %>
+ </p>
+
+ <p>
+ <span id="tame_expr" class = "bookmark"></span>
+ <b class="header">Tame in an Expression Context</b>
+ It's possible
+ to use <tt>await</tt> blocks as expressions. And recursively
+ speaking, it's possible to use statements that contain `await`
+ blocks as expressions.
+ </p>
+
+ <p>
+ The simple rule is that an <tt>await</tt> block takes on the value of the
+ <tt>defer</tt> slot named <tt>_</tt> after its been fulfilled. If there
+ are multiple defer slots named <tt>_</tt> within the await block, then
+ the last writer wins. In practice, there's usually only one. Thus:
+ </p>
+
+ <p><%= code_for('tame_expr_1', true) %></p>
+
+ <p>
+ Of course, things can get arbitrarily compicated and nested, so it
+ gets hairy. Consider this:
+ </p>
+
+ <p><%= code_for('tame_expr_2', true) %></p>
+
+ <p>
+ The rule is that all nested <tt>await</tt> blocks (barf!) are evaluated
+ sequentially in DFS order. You will get <tt>10</tt> in the above example
+ after three sequential calls to <tt>add</tt>.
+ </p>
+
+ <p>
+ I really don't like this feature for two reasons: (1) it's tricky to
+ get the implementation right, and I'm sure I haven't tested all of the
+ corner cases yet; (2) it's difficult to read and understand what
+ happens in which order. I would suggest you save yourself the heartache,
+ and just write the above as this:
+ </p>
+ <p><%= code_for('tame_expr_3', true) %></p>
+
+ <p>
+ It's just so much clearer what happens in which order, and it's easier
+ to parallelize or serialize as you see fit.
+ </p>
<p>
<span id="literals" class="bookmark"></span>
@@ -0,0 +1,12 @@
+var __tame_deferrals, __tame_k,
+ _this = this;
+
+__tame_k = function() {};
+
+(function(__tame_k) {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ setTimeout(__tame_deferrals.defer({}), 1000);
+ __tame_deferrals._fulfill();
+})(function() {
+ return alert("back after a 1s delay");
+});
@@ -0,0 +1,28 @@
+var __tame_deferrals, __tame_k,
+ _this = this;
+
+__tame_k = function() {};
+
+window.slowAlert = function(w, s, cb) {
+ var __tame_deferrals,
+ _this = this;
+ (function(__tame_k) {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ setTimeout(__tame_deferrals.defer({}), w);
+ __tame_deferrals._fulfill();
+ })(function() {
+ alert(s);
+ return cb();
+ });
+};
+
+(function(__tame_k) {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ slowAlert(500, "hello", __tame_deferrals.defer({}));
+ slowAlert(1000, "friend", __tame_deferrals.defer({}));
+ __tame_deferrals._fulfill();
+})(function() {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ slowAlert(500, "back after a delay", __tame_deferrals.defer({}));
+ __tame_deferrals._fulfill();
+});
@@ -0,0 +1,39 @@
+var dns, err, host, ip, __tame_deferrals, _i, _len, _next, _ref, _while,
+ _this = this;
+
+__tame_k = function() {};
+
+dns = require('dns');
+
+_ref = ['yahoo.com', 'google.com', 'nytimes.com'];
+_len = _ref.length;
+_i = 0;
+_while = function(__tame_k) {
+ var _break, _continue;
+ _break = __tame_k;
+ _continue = function() {
+ ++_i;
+ return _while(__tame_k);
+ };
+ _next = _continue;
+ if (_i < _len) {
+ host = _ref[_i];
+ (function(__tame_k) {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ dns.resolve(host, "A", __tame_deferrals.defer({
+ assign_fn: (function() {
+ return function() {
+ err = arguments[0];
+ return ip = arguments[1];
+ };
+ })()
+ }));
+ __tame_deferrals._fulfill();
+ })(function() {
+ return _next(err ? console.log("Error for " + host + ": " + err) : console.log("Resolved " + host + " -> " + ip));
+ });
+ } else {
+ return _break();
+ }
+};
+_while(__tame_k);
@@ -0,0 +1,47 @@
+var x, __tame_deferrals,
+ _this = this;
+
+__tame_k = function() {};
+
+window.add = function(a, b, cb) {
+ var __tame_deferrals,
+ _this = this;
+ (function(__tame_k) {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ setTimeout(__tame_deferrals.defer({}), 10);
+ __tame_deferrals._fulfill();
+ })(function() {
+ return cb(a + b);
+ });
+};
+
+(function(__tame_k) {
+ return (function(__tame_k) {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ add(3, 4, __tame_deferrals.defer({
+ assign_fn: (function() {
+ return function() {
+ return __tame_deferrals.ret = arguments[0];
+ };
+ })()
+ }));
+ __tame_deferrals._fulfill();
+ })(function(___tame_p__2) {
+ return (function(__tame_k) {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ add(1, 2, __tame_deferrals.defer({
+ assign_fn: (function() {
+ return function() {
+ return __tame_deferrals.ret = arguments[0];
+ };
+ })()
+ }));
+ __tame_deferrals._fulfill();
+ })(function(___tame_p__1) {
+ return __tame_k(___tame_p__2 + ___tame_p__1);
+ });
+ });
+})(function(___tame_p__0) {
+ x = ___tame_p__0;
+ return alert("" + x + " is 10");
+});;
@@ -0,0 +1,42 @@
+var x, __tame_deferrals,
+ _this = this;
+
+__tame_k = function() {};
+
+(function(__tame_k) {
+ (function(__tame_k) {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ add(1, 2, __tame_deferrals.defer({
+ assign_fn: (function() {
+ return function() {
+ return __tame_deferrals.ret = arguments[0];
+ };
+ })()
+ }));
+ __tame_deferrals._fulfill();
+ })(function(___tame_p__5) {
+ return (function(__tame_k) {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ add(3, 4, __tame_deferrals.defer({
+ assign_fn: (function() {
+ return function() {
+ return __tame_deferrals.ret = arguments[0];
+ };
+ })()
+ }));
+ __tame_deferrals._fulfill();
+ })(function(___tame_p__4) {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ add(___tame_p__5, ___tame_p__4, __tame_deferrals.defer({
+ assign_fn: (function() {
+ return function() {
+ return __tame_deferrals.ret = arguments[0];
+ };
+ })()
+ }));
+ __tame_deferrals._fulfill();
+ });
+ });
+})(function(___tame_p__3) {
+ return x = ___tame_p__3;
+});;
@@ -0,0 +1,38 @@
+var l, r, x, __tame_deferrals,
+ _this = this;
+
+__tame_k = function() {};
+
+(function(__tame_k) {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ add(1, 2, __tame_deferrals.defer({
+ assign_fn: (function() {
+ return function() {
+ return l = arguments[0];
+ };
+ })()
+ }));
+ __tame_deferrals._fulfill();
+})(function() {
+ (function(__tame_k) {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ add(3, 4, __tame_deferrals.defer({
+ assign_fn: (function() {
+ return function() {
+ return r = arguments[0];
+ };
+ })()
+ }));
+ __tame_deferrals._fulfill();
+ })(function() {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ add(l, r, __tame_deferrals.defer({
+ assign_fn: (function() {
+ return function() {
+ return x = arguments[0];
+ };
+ })()
+ }));
+ __tame_deferrals._fulfill();
+ });
+});
@@ -0,0 +1,35 @@
+var __slice = Array.prototype.slice;
+
+window.tame = {
+ Deferrals: (function() {
+
+ function _Class(_arg) {
+ this.continuation = _arg;
+ this.count = 1;
+ this.ret = null;
+ }
+
+ _Class.prototype._fulfill = function() {
+ if (!--this.count) return this.continuation(this.ret);
+ };
+
+ _Class.prototype.defer = function(defer_params) {
+ var _this = this;
+ ++this.count;
+ return function() {
+ var inner_params, _ref;
+ inner_params = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
+ if (defer_params != null) {
+ if ((_ref = defer_params.assign_fn) != null) {
+ _ref.apply(null, inner_params);
+ }
+ }
+ return _this._fulfill();
+ };
+ };
+
+ return _Class;
+
+ })()
+}
+window.__tame_k = function() {};
@@ -0,0 +1,25 @@
+var i, __tame_deferrals, _i, _next, _while,
+ _this = this;
+
+__tame_k = function() {};
+
+i = 0;
+_while = function(__tame_k) {
+ var _break, _continue;
+ _break = __tame_k;
+ _continue = function() {
+ ++i;
+ return _while(__tame_k);
+ };
+ _next = _continue;
+ if (i <= 3) {
+ (function(__tame_k) {
+ __tame_deferrals = new tame.Deferrals(__tame_k);
+ slowAlert(200, "loop iteration " + i, __tame_deferrals.defer({}));
+ __tame_deferrals._fulfill();
+ })(_next);
+ } else {
+ return _break();
+ }
+};
+_while(__tame_k);
@@ -0,0 +1,9 @@
+var i, __tame_deferrals, __tame_k, _i;
+
+__tame_k = function() {};
+
+__tame_deferrals = new tame.Deferrals(__tame_k);
+for (i = _i = 0; _i <= 3; i = ++_i) {
+ slowAlert(200, "loop iteration " + i, __tame_deferrals.defer({}));
+}
+__tame_deferrals._fulfill();
Oops, something went wrong. Retry.

0 comments on commit 92c9299

Please sign in to comment.