>From a brief look, this looks very similar to the model used by TameJS or Iced CoffeeScript, both of which use an approach rooted in await / deferred semantics and AST parsing and rewriting. Are you aware of those projects? If so, how is your approach different? Also, aside from slightly terser syntax, what does this approach offer over promises, which don't require a preprocessing step?
I don't intend to sound dismissive or hostile, but there are a massive number of flow control libraries for JS / Node, and a considerable amount of this list's history tied up in arguing their relative merits, which is part of the reason why Node has such a minimal / primitive model for dealing with continuations in the first place. New flow control tools are unlikely to see much uptake unless they bring something significant and new (that justifies the time taken to learn them and the cost of maintaining code that looks different from more idiomatic JS) to the table. F On Monday, December 10, 2012, Jonathan Dickinson wrote: > Hi All, > > I just started my first foray into javascript beyond the usual minimal > glue I was used with browsers. After looking at some node tutorials the > first thing I noticed was the CPS hell (honestly, no way in hell I am > dealing with that ;)). I present an extremely rough draft of asyncscript; > it modelled after (black-box) looking at how C# implements its async. > https://github.com/jcdickinson/asyncscript > > The metacompiler first takes an AST (lightly modified acorn.js) and turns > in into IR. The IR basically adds blocks and closures to the AST, so you > essentially land up with: > > - Closure > - Block1 > - AST > - Block2 > - AST > - Block3 > - AST > - Closure > - ... > - AST > > Blocks are breaks in real execution (read: continuations - although I will > also need to [ab]use them for branching constructs in the presence of the > async keyword). The IR is then passed off to a few transformation stages > (async, if, &&/||, while, for - of which only async is implemented). So for > example, the async transform will create a split in the block (resulting in > two blocks) at the statement containing the async keyword. > > - Closure (async) > - Block1 > - AST that was in Block1 before await > - await > - Block2 > - grab async result > - AST that was in Block1 after await > > Finally the IR is turned into JS. Due to the lack of a goto statement in > JS I needed to implement 'transitioning' blocks (if, and other > non-continuation branches) as a while loop: > > var state = 0; > while(true) { > switch(state) { > case 0: > blar(); > state = 1; // Effectively a goto > break; > case 1: > baz(); > return; > } > } > > Yes, it's ugly, but I would rather have ugly code than bloating the call > stack (please, does anyone has any better ideas how to do this without > wasting stack space?). 'sequencing' blocks simply return out of the > function after registering the continuation. So at the end of the day you > get: > > asyncscript: > var username = "jimbob"; > var settings = await httpGetAsync("http://myserver/?username=" + > username); > await displaySomeModal(settings); > > javascript (tidied): > (function () { > var state = 0; > var awaiter = createAwaiter(); > function continuation() { > try { > var result = arguments[1]; > if (typeof arguments[2] !== 'undefined') throw arguments[2]; > state = arguments[0]; > while (true) { > switch (state) { > case 0: { > username = "jimbob"; > await(continuation, 1, httpGetAsync(" > http://myserver/?username=" + username)); > return; > } > case 1: { > tmp = result; > settings = tmp; > await(continuation, 2, displaySomeModal(settings)); > return; > } > case 2: { > completeAwaiter(continuation); > return; > } > default: > throw 'The runtime has become unstable.'; > } > } > } catch (error) { > completeAwaiter(continuation, null, error); > return; > } > } > continuation(0); > return createPromise(awaiter); > })(); > > As I said, this is my first serious attempt at JS - so I might have made > some obvious mistakes (quite possibly messing up the closure semantics, but > I think I got it right). Feel free to tell me (in a justified way) how I am > a noob :), also remember that this is a draft: so a very small amount of > the JS syntax is actually implemented. I would just like some feedback > before making something that is complete but blatantly incorrect. > > I am also [ab]using AMD for the purposes of loading in different > 'runtimes' (code generators that define how e.g. completeAwaiter and > createPromise, are generated) for the purposes of e.g. jquery v.s. > node-promise. I might be doing the totally wrong thing, but thought it was > pretty cool. I will also fix the folder layout some time later: at the > moment it hacks in intellisense support for VS2012. > > If you think it's beyond help and want to re-implement it, I don't mind at > all: I would be happy to contribute code and ideas to a repo maintained by > someone who knows what they are doing. > > -- > jcd > > -- > Job Board: http://jobs.nodejs.org/ > Posting guidelines: > https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines > You received this message because you are subscribed to the Google > Groups "nodejs" group. > To post to this group, send email to > [email protected]<javascript:_e({}, 'cvml', '[email protected]');> > To unsubscribe from this group, send email to > [email protected] <javascript:_e({}, 'cvml', > 'nodejs%[email protected]');> > For more options, visit this group at > http://groups.google.com/group/nodejs?hl=en?hl=en > -- Job Board: http://jobs.nodejs.org/ Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines You received this message because you are subscribed to the Google Groups "nodejs" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en
