Yeah, most of your requirements are ones that I agree with and believe
that Promises/A and Promises/B both satisfy and have satisfied. If I
don't mention in this email one of the requirements you feel are not
satisfied, please follow-up and I'll try to explain. The upshot is
that I think we're largely in agreement philosophically. Here are the
exceptions:
Regarding "joins", "when" is the only primitive we need. A *wide*
variety of conjunctions can be sensibly and readably constructed in
terms of that one function. Most other forms are solved better by
closures and Array's "reduce" function than more methods.
https://github.com/kriskowal/q-util/blob/master/lib/q-util.js
I disagree that promises are merely a codification of a callback.
They model both of the behaviors of function control-flow projected
into the asynchronous control-flow world: return values *AND*
exceptions, particularly that an ignored exception percolates
implicitly. There are numerous other reasons that both Promises/A and
Promises/B are far more than just callback styles, and certainly
useful in the absence of joining utilities which can be trivially
implemented by libraries in terms of the promises primitives.
It is trivial to implement a timeout without any additional effort in the spec:
setTimeout(deferred.reject, 1000);
Multiple resolutions are a composition hazard. You would end up with
confused clients. If you need multiple calls, you need to use an
event emitter, not a promise, or a function call that returns a
promise for the most recently, or first eventually emitted value. In
any case, no work is needed on our part.
As for the deferred methods bike-shed, I'm quite content with the bits
that Kris Zyp, Tyler Close, and I appear to all be in agreement on so
far: "resolve", "reject", and all that.
Regarding protection, I continue to be in agreement with Mark Miller
and Tyler Close that cleanly separating the "promise" and "resolve"
components of a "defer" result solves the problem, and is not
syntactically expensive enough in practice to fuss about. I almost
always buy peace-of-mind when it's on sale. I don't think unfrozen
promises are likely to be useful in environment where frozen promises
are available.
"get", "put", "post", and "del" are important and Tyler Close's
implementation illuminates that providing hooks for these "extensions"
to the specification is at least important, but I'm not about to press
for a vote on Promises/A vs Promises/B. We Kris's have cast our bets
with our respective proposals and are building out essentially
competing ecosystems. Nathan Stott is presently trying to figure out
exactly how difficult it is to exchange code between these systems,
which is probably the most useful thing anybody could be doing about
promises right now since it reveals details inherent to our
assumptions. Meanwhile, I will be working with Mark Miller, Terry
Stanley, Tyler Close, and Dirk Neumann to port utilities for the
already vetted remote promise object methods, get/put/post/del to
demonstrate their worth in some of our mutual projects. In the worst
case, they are easy enough to ignore.
Kris Kowal