Whoops, maybe scratch the "monadic" part - it would still be impossible to create a promise for a promise. It would however be possible to protect thenables.
On Wed, Feb 5, 2014 at 2:17 AM, Gorgi Kosev <[email protected]> wrote: > Not sure if this is correct, but: This might actually be (perhaps > accidentally) one step closer to allowing promises for thenables in a > cleaner way *if* the need arises in the future. > > Since its impossible to create a promise for a promise now, it would be > *theoretically* possible (at some point in the future) to just > > * introduce `Promise.of` (wraps thenables) > * make `.then` unwrap "true" promises only once > * make `resolve` cast thenables into promises that recursively unwrap > thenables > > and be done. You'd have > > * `Promise.of` - wraps thenables, returns promises, wraps other values > * `resolve` - converts thenables to recursively unwrapping promises, > returns promises, wraps other values > * `.then(f, r)` - for values returned by the handlers: recursively unwraps > thenables, unwraps promises once, wraps other values > > > After that, you could use `.then` in a monadic way, provided you remember > to protect thenables with `Promise.of` (should not be a problem with typed > compile-to-js languages). e.g. `resolve(Promise.of(thenable))` or `p.then(x > => Promise.of(thenable))` You could also implement `.map` using `.then` > and `Promise.of` > > Previously you'd have to make `resolve` and `Promise.cast` the same before > making `.then` unwrap a single level. Alternatively, you'd have to > introduce `.chain` and have a confusing dual API (chain/then, > resolve/cast). > > > > On Tue, Feb 4, 2014 at 8:31 PM, Brendan Eich <[email protected]> wrote: > >> Tab Atkins Jr. wrote: >> >>> On Tue, Feb 4, 2014 at 10:55 AM, Rick Waldron<[email protected]> >>> wrote: >>> >>>> > Per Resolution >>>> > (https://github.com/rwaldron/tc39-notes/blob/master/es6/ >>>> 2014-01/jan-30.md#conclusionresolution-3) >>>> > >>>> > - Promise.cast is renamed to Promise.resolve (remove old >>>> Promise.resolve) >>>> > - Keep then, reject chain (NOT DEFER, reject!) >>>> > - Renaming .cast thus removes over-wrapping (always-wrap) >>>> deoptimization in >>>> > old Promise.resolve >>>> >>> >>> Okay, so this is discarding the previous consensus, right? Monadic >>> promises are thrown out? >>> >> >> Fundamental conflict between .chain and .then, on three levels: >> >> 1. Committee "do both" / union proposals smell and bloat -- this is a >> problem _per se_. >> >> 2. All the standard combinators call .then not .chain. >> >> 3. Including .chain requires always-wrapping resolve, observability >> trumps optimizability. >> >> There's really a 0 implicit in this: >> >> 0. Monadic vs. non-monadic is an exclusive or -- you can't "have it all". >> >> This breaks async maps forever, then. :/ With the previous consensus, >>> the result promise from an async map could be observed directly with >>> .chain(), and it worked great regardless of what was stored inside the >>> map. >>> >>> With only flat promises, if you store a promise in an async map and >>> then try to retrieve it later, the error callback gets called if the >>> key wasn't in the map*or* the key was in the map, but the stored >>> >>> value was a rejected promise. You have to spread your program logic >>> over both callbacks to catch that case (or more likely, people will >>> just write programs that break occasionally because they assumed that >>> the reject branch of the AM.get() promise is only for failed lookups, >>> as the documentation probably says). >>> >> >> This does seem like a problem in the async map API, but I bet it can be >> solved without taking the hit of 1-3 above. Overloading get's return value >> is the root of the evil. Hand-boxing disambiguates the r.v. >> >> Similarly, if you store a forever-pending promise in the async map, >>> it's impossible to ever retrieve it. Even just a long-pending promise >>> will stall your program's logic while it waits, preventing you from >>> updating UI when the map returns and*then* completing the operation >>> >>> when the stored promise finally resolves. >>> >> >> This, I don't buy. You have to hand-box using {value: } or whatever. >> >> >> The only way to get a working async map is to defensively store your >>> values in a single-element array (or some other non-promise wrapper >>> object) and unwrap them on retrieval. >>> >> >> Right, hand-box. That's the price of the XOR between Monadic and >> anti-Monadic promises, and anti-monadic already won in the library >> evolution of Promises. >> >> >> Pretending that all promises are identical identity-less wrappers that >>> can be arbitrarily collapsed is such a mistake.>_< >>> >> >> There are no great paths forward. I would like to make promises value >> objects, E-like. But it's too late. Promises happened, the DOM and ES6 need >> them, worse is better. You knew that already! >> >> /be >> >> _______________________________________________ >> es-discuss mailing list >> [email protected] >> https://mail.mozilla.org/listinfo/es-discuss >> > >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

