<div dir="ltr">[+es-discuss]<div><br></div><div style>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. </div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jun 4, 2013 at 8:32 AM, Mark S. Miller <span dir="ltr"><<a href="mailto:erights@google.com" target="_blank">erights@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div class="h5">On Tue, Jun 4, 2013 at 7:34 AM, Domenic Denicola <span dir="ltr"><<a href="mailto:domenic@domenicdenicola.com" target="_blank">domenic@domenicdenicola.com</a>></span> wrote:<br>
</div></div><div class="gmail_extra">
<div class="gmail_quote"><div><div class="h5"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>On Tue, Jun 4, 2013 at 9:48 AM, Anne van Kesteren <<a href="mailto:annevk@annevk.nl" target="_blank">annevk@annevk.nl</a>> wrote:<br>


<br>
> On Tue, Jun 4, 2013 at 8:55 AM, Sam Tobin-Hochstadt <<a href="mailto:samth@ccs.neu.edu" target="_blank">samth@ccs.neu.edu</a>> wrote:<br>
>> Thinking about this more, I'm now unsure why both `fulfill` and<br>
>> `resolve` are needed given the semantics of `.chain()` and `.then()`<br>
>> described below.<br>
>><br>
>> In particular, if `.then()` chains recursively *before* calling the<br>
>> callback, then there's no difference between:<br>
>><br>
>>     Future.resolve(x).then(v => ...)<br>
>><br>
>> and<br>
>><br>
>>     Future.fulfill(x).then(v => ...)<br>
>><br>
>> even when `x` is a promise.  The only way to observe this is with `.chain()`.<br>
>><br>
>> Thoughts?<br>
><br>
> I'm just going to try to repeat what you said here to make sure I understand.<br>
><br>
> Promise.resolve(val) creates a promise of val, regardless of whether<br>
> val is a promise, has a callable then property, or anything like that.<br>
> (In that sense it is equivalent to Future.accept() today.)<br>
><br>
> promise.then() keeps unwrapping promise's internal value until it no<br>
> longer has a callable then property at which point it invokes the<br>
> relevant callback passed to promise.then(). (Exact algorithm TBD after<br>
> broader agreement.)<br>
><br>
> promise.chain() invokes its relevant callback with promise's internal value.<br>
><br>
> promise.then() and promise.chain() return value (newPromise) is<br>
> resolved with the return value of their callbacks after it has been<br>
> unwrapped once.<br>
<br>
</div>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`.<br>

</blockquote><div><br></div></div></div><div>Agreed. This is a great direction. Thanks, Sam!</div><div><br></div><div>Given this direction, I think the one operation that serves as both Promise.resolve and Promise.fulfill should be the previously suggested Promise.of.</div>
<div class="im">
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
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?<br>

</blockquote><div><br></div></div><div>If you don't unwrap[1] 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 <b><u><i>*HUGE*</i></u></b>! 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 <<a href="http://wiki.ecmascript.org/doku.php?id=strawman:async_functions#reference_implementation" target="_blank">http://wiki.ecmascript.org/doku.php?id=strawman:async_functions#reference_implementation</a>> would need to accumulate a level of nesting per iteration of the loop.</div>
<div class="im">
<div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
I also think the name "chain" is pretty confusing, especially in light of already-existing terminology around promise chaining [1]. Is there precedence for it in other languages? flatMap seems clearest to me so far.<br>


<br>
[1]: <a href="https://www.google.com/search?q=promise+chaining" target="_blank">https://www.google.com/search?q=promise+chaining</a><br>
</blockquote></div></div><br><br></div><div class="gmail_extra">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.<br>

<br><div><br></div><div>[1] 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. </div>
<span class="HOEnZb"><font color="#888888">
<div><br></div><div><br></div>-- <br>    Cheers,<br>    --MarkM
</font></span></div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>    Cheers,<br>    --MarkM
</div>