I am aware that I'm kicking a potentially angry beehive by bringing up this
topic, but I wanted to just have some discussion around if there's any
added to it for better managing of sync vs. async coding patterns, without
The more formalized approach to this topic is typically labeled "promises"
(and/or "defers"). While what I'm going to propose is going to borrow some
language and ideas from that crowd, let me just say: *I am not qualified as
anything remotely like proficient in all the ins and outs of
formalized stuff down into some simpler ideas, and explore ways that
I will not bog down this email thread with a detailed description of all the
problems with callbacks, but I encourage you to read the first half of my
most recent blog post, as I go into much detail about those issues there.
It's *not* just a question of syntactic sugar -- I believe there's a
fundamental paradigm with callbacks that is deficient, and actually *that*
is my primary motivator. Where my proposal will have possibly
shorter/simpler syntax, i consider that a benefit, but not the primary
Moreover, I don't necessarily want to stoke the flames of syntactic
perferences. I'd rather discuss some underlying basic pieces of the puzzle.
Also, Brendan suggested exactly the same -- that we start with discussion of
the semantics and exeuction model, rather than syntax.
My proposal (semantics/processing model first, syntax second) is located in
the second half of that post, here:
???? X(1,2) ???? Y(3,4) ???? Z("foo") ????;
`X`, `Y`, and `Z` are all possibly function calls which will not complete
synchronously, but may defer their fulfillment asynchronously until a later
The spirit of the proposal is that this special type of statement be a
linear sequence of function executions (as opposed to nested
function-reference callbacks delegating execution to other code).
The special behavior is that in between each part/expression of the
statement, evaluation of the statement itself (NOT the rest of the program)
may be "suspended" until the previous part/expression is fulfilled. This
would conceptually be like a yield/continuation localized to ONLY the
statement in question, not affecting the linear execution of the rest of the
The model for the suspension and resuming of such evaluation would be, under
the covers, identical (as much as possible) to how async callbacks are
deferred to execute until a later time (turn based, etc).
Any regular statement that appears after this special type of statement
would be evaluated/executed as soon as either the statement in
question completes (if all parts are in fact synchronous and not-deferred),
or as soon as some part of the statement in question defers, to "suspend"
evaluation of the rest of the statement.
There are other details to the proposed mechanism, including "message
passing" between each step in the sequence of expressions in the statement,
and also conditional execution, for allowing both a "success" and "failure"
path to be defined. "Success" path would be taken if the deferred/suspended
expression fulfills itself under expected conditions, and "Failure" path
otherwise. The mechanism would ensure that only one of either the "success"
or "failure" paths was taken for any particular deferral/suspension upon
Lastly, no special behavior with respect to the state of surrounding
variables/scope is implied during the resumed-from-suspension execution of
the statement. Normal scoping/closure rules would apply, meaning the current
state at time of resume would be respected.
I'm not trying to solve all of the possible issues/use-cases with dealing
with complex async/chained logic through promises/defers. I'm not suggesting
that noone will ever have to use a promise/defer "lib" of some sort again
for the more complex negotiation tasks. I'm not suggesting that my
proposal will be the cure all.
What I am suggesting is that the best first step to take in helping deal
narrowly defined, natively implemented mechanism, which will serve as a
building block for more complex usage, and will simultaneously provide very
streamlined and simple syntax for a wide array of common sync/async tasks
(like event binding, etc).
I welcome any thoughts/feedback on the viability of such a proposal, or
pitfalls or structural shortcomings I may not have forseen yet. But again,
let's not get mixed up in the weeds of syntax preference just yet.
Kyle (aka @getify)
es-discuss mailing list