Deprecating Future's .then()
Mark S. Miller
erights at google.com
Tue Jun 4 08:42:45 PDT 2013
I just realized that this thread has occurred so far only on the wrong
lists. Please let's proceed from here only on es-discuss. This is a
language issue, not a browser issue. Let's please stop splitting the
discussion between two communities.
On Tue, Jun 4, 2013 at 8:32 AM, Mark S. Miller <erights at google.com> wrote:
> On Tue, Jun 4, 2013 at 7:34 AM, Domenic Denicola <
> domenic at domenicdenicola.com> wrote:
>> On Tue, Jun 4, 2013 at 9:48 AM, Anne van Kesteren <annevk at annevk.nl>
>> > On Tue, Jun 4, 2013 at 8:55 AM, Sam Tobin-Hochstadt <samth at ccs.neu.edu>
>> >> Thinking about this more, I'm now unsure why both `fulfill` and
>> >> `resolve` are needed given the semantics of `.chain()` and `.then()`
>> >> described below.
>> >> In particular, if `.then()` chains recursively *before* calling the
>> >> callback, then there's no difference between:
>> >> Future.resolve(x).then(v => ...)
>> >> and
>> >> Future.fulfill(x).then(v => ...)
>> >> even when `x` is a promise. The only way to observe this is with
>> >> Thoughts?
>> > I'm just going to try to repeat what you said here to make sure I
>> > Promise.resolve(val) creates a promise of val, regardless of whether
>> > val is a promise, has a callable then property, or anything like that.
>> > (In that sense it is equivalent to Future.accept() today.)
>> > promise.then() keeps unwrapping promise's internal value until it no
>> > longer has a callable then property at which point it invokes the
>> > relevant callback passed to promise.then(). (Exact algorithm TBD after
>> > broader agreement.)
>> > promise.chain() invokes its relevant callback with promise's internal
>> > promise.then() and promise.chain() return value (newPromise) is
>> > resolved with the return value of their callbacks after it has been
>> > unwrapped once.
>> In general, this approach is extremely interesting. The shift from
>> focusing on promise fulfillment and being in the three states of pending,
>> fulfilled, and rejected to focusing on promise resolution and being in the
>> two "fates" of unresolved and resolved is a big difference. But it is
>> probably a win as it ends up eliminating the state concept almost entirely,
>> making it just an emergent way of describing what happens with `then`.
> Agreed. This is a great direction. Thanks, Sam!
> Given this direction, I think the one operation that serves as both
> Promise.resolve and Promise.fulfill should be the previously suggested
>> One point I am not entirely clear on is why there is *any* unwrapping of
>> return values, as in the last step Anne describes. For consumption with
>> `then` it seems to make no difference. I assume this is to match flatMap or
>> bind semantics from other languages, so that if you use `chain` exclusively
>> you match Haskell/Scala/et al. semantics?
> If you don't unwrap at all, i.e., go with a .map-like treatment of
> return values, rather than a .flatMap-like treatment, the difference is
> unobservable to those who use .then exclusively, and the semantics seems
> simpler, so this would seem to be a win. But the storage costs would be *
> *HUGE**! Since the implementation can't in general tell whether a promise
> will be observed with .chain or .then later, it would have to preserve each
> level of nesting for .then calls nested in .then calls. This would lose the
> flattening property that corresponds to being insensitive to how many
> levels deep in a function call chain a value was returned from. The normal
> tail-recursive promise loop pattern <
> would need to accumulate a level of nesting per iteration of the loop.
>> I also think the name "chain" is pretty confusing, especially in light of
>> already-existing terminology around promise chaining . Is there
>> precedence for it in other languages? flatMap seems clearest to me so far.
>> : https://www.google.com/search?q=promise+chaining
> I agree. This terminology will lead to confusion: "To do promise chaining,
> use .then. The .chain method doesn't support promise chaining." As for
> .flatMap, I am indifferent, since I'm planning to avoid it myself. I leave
> it to its advocates to suggest something unconfusing.
>  I am always worried though when people use the term "unwrapping" as I
> don't know what they mean. Does this mean flattening, assimilating, both,
> or something else? What I mean here is to so one level of flattening. As
> for whether .then should also do one level of assimilation if it sees a
> non-promise thenable, I could go either way, but prefer that it should not.
> The promise-cross-thenable case should be sufficiently rare that the cost
> of the extra bookkeeping should be negligible.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the es-discuss