Re: Deprecating Future's .then()

+1 on all counts regarding mechanism. As for how happy the conclusion is, I
remain skeptical. But **given that** we cannot get consensus in TC39
without support for Promise.fulfill, as was obvious in the London/May
meeting, I do agree that AP2 as Tab describes here is our best option.
We'll see how happily the two styles actually co-exist in practice.

I'll hazard a prediction: the Q style continue to dominate. The
.fulfill/.flapMap means of tunneling a fully parametric value through
Q-style abstractions will prove unsatisfactory in practice, and people will
instead use the {value: x} style. The Q-style folks will be happy in that
they can proceed ignoring the existence of .fulfill and .flatMap, as Tab
correctly observes.

The .flatMap-style folks will be unhappy with the unreliability of using
.fulfill/.flatMap to tunnel through Q-style abstractions. Eventually they
will either
a) treat the two styles as two different universes that do not
interoperate, and so should have simply been disjoint abstractions, or
b) give up and use the {value: x} style wrapper to tunnel through promise
abstractions reliably.
In either case, in retrospect it will have turned out to be a mistake to
try to support both styles with the one API. But a mistake we will mostly
be able to ignore. We've lived with worse.




On Mon, Jun 3, 2013 at 2:00 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:

> On Mon, Jun 3, 2013 at 11:21 PM, Anne van Kesteren <annevk@annevk.nl>
> wrote:
> > On Mon, Jun 3, 2013 at 3:13 PM, Mark S. Miller <erights@google.com>
> wrote:
> >> Me too. I find your points about why AP2 (recursive unwrapping of
> callback
> >> argument) is superior to AP3 (recursive unwrapping of callback result)
> >> persuasive.
> >
> > Interesting, how would that work?
>
> 1. Promises have both unconditional lift (Future.accept/fulfill) and
> conditional lift (Future.resolve).
>
> 2. If you register a .then() callback, and the promise resolves to
> another promise, it will move the callbacks down to the inner promise;
> this continues until it finally resolves to a non-promise value, at
> which point the callbacks are called.  If the callback returns a
> non-promise value, the chained promise fulfills to that; if it returns
> a promise, the chained promise adopts its state in a non-recursive
> manner, fulfilling directly to the same value as the returned promise.
>
> 3. Promises sprout another method, called .chain() or .flatMap() or
> something, that doesn't do these bits of magic.  It calls its
> callbacks as soon as the promise fulfills, regardless of what type of
> value it fulfills to.  The callback return value must be a promise
> (rejecting the chained promise with a TypeError if not, I suppose),
> and the chained promise adopts its state.
>
> Done!  This allows both methods of promise manipulation (promises as
> flow control, and promises as containers) to transparently
> interoperate arbitrarily, so consumers can choose at every point in
> the chain whether they want to fully flatten or just get the immediate
> inner value.  You never have to choose one method as "canonical" and
> break anything that wants to use the other method.
>
> ~TJ
>



-- 
    Cheers,
    --MarkM

Received on Monday, 3 June 2013 21:20:31 UTC