Try streamline.js (https://github.com/Sage/streamlinejs)
It uses a slightly different syntax (underscore parameter instead of await operator) but it handles *all* JavaScript constructs. For example, it supports async calls in exception handling constructs (both try/catch and try/finally) as well as async calls nested at any level in subexpressions. It also handles long-stack-trace with line numbers that match the source lines + a few other goodies. And there is an "await" branch (still experimental but the basics work) if you don't like the underscore syntax. Bruno On Tuesday, December 11, 2012 10:02:45 AM UTC-8, Jonathan Dickinson wrote: > > Oh wow. That's awesome: I had no idea that these projects existed. The > approach with the defer keyword is incredibly interesting (I assume the > existence of some promise library, like JQuery or node-promise). For what > it's worth I set out to avoid heavy dependence on the stack: it seems that > after some brief testing Iced and Tame are quite resilient to this. > > They are compiled really differently to mine: just take a look at the > comparative output. > > Some criticisms: > > - Iced can't compile this: await (await test(baz, defer), defer) > Not surprising, it could be seen as ambiguous, but this is currently > compiling (and running) locally for me: await test(await baz(), await > blaz()); > - Tame doesn't deal with exceptions too well. Likely because their > compilation technique is very different to mine (maybe because they make > 'typical' continuations, or, because they don't use promises). I can't > tell > if Iced does. > - After some searching I couldn't tell if either of them have > sourcemap support. > > I'm not convinced I should continue with asyncscript though. Those are > pedantic criticisms at best (except for the sourcemap: Iced results in > pretty hard to debug code - which I am sure will be supported eventually). > > Thanks for the heads-up. > > On Tuesday, 11 December 2012 17:59:03 UTC+2, Forrest L Norvell wrote: >> >> 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] >>> 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 >>> >> -- 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
