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

Reply via email to