-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Propagate fulfilled value as it is #221
Conversation
This is in fact not correct; thenables should be recursively resolved. I'll let @kriskowal confirm, but generally the consensus has been that See also promises-aplus/promises-spec#76 |
Yes, returning a thenable implicitly attempts to coerce that to a promise. Marking objects with "then" methods that are not indeed promises is probably the only legitimate use of |
A resolved value is a resolved value, and it should be propagated as such. Returned values form callbacks, in other hand, should be recursively resolved. Otherwise Q is broken if resolved value is also a thenable. |
No, a fulfilled value is a fulfilled value; a resolved value is propagated. Q is not "broken" if a resolved value is a thenable. Q is simply incompatible with thenables where |
Ok, I will use the fulfilled word then... |
Right, I believe that our view is that it's impossible for a thenable to have a legitimate fulfillment value that is a thenable; it is our responsibility to squash chains of "x represents something that represents y" into "x represents y". |
Why not?! Why you are not willing to distinguish already fulfilled/rejected values from returned values/promises from callbacks? |
@rkatic It is not so much a question of willing as able. Detecting whether an object is a thenable or just happens to have a "then" method is very messy. If it is not a thenable promise, we should not be calling its then method, and even calling the then method is not sufficient in every case to distinguish it from a promise, a badly behaving promise, a poorly implemented promise, or not a promise at all. |
The distinction that I am talking about doesn't go against Promise/A+. |
@rkatic I believe it does go against Promises/A+ 1.1, though, as per the earlier-linked issue. |
I am not buying this. Also I have not time to read all your discussions about. If you can point me out the reason of such drastic decision, I will be grateful. |
"Drastic," lol. This is an edge case by any definition. I think I explained it rather well above. Promises represent values. Conceptually, promises for promises are nonsensical: they are chains of "x represents something that represents y," which really just should be collapsed to "x represents y." Furthermore, promises for promises are hazardous, but I won't bother trying to link you somewhere demonstrating this, since you are too busy to read any reasoning longer than a few sentences it seems. As for the difference between "promise for promise for x" and "promise for thenable for x," @kriskowal explained this well above: we simply don't have the ability to tell the difference, so we assume in good faith that thenables are promises. Anyone who really needs to use non-promise thenables while also wanting to use a promise system will take the effort to wrap it in e.g. |
Thanks for your effort @domenic. I am a lazy bastard. However, I still don't see why your arguments should be sound. When the |
I agree. But only promise implementations call |
Well, then my question is what is your argument for your argument :) |
Sadly I don't think I can repeat myself any longer. You should never have a promise for a promise, as I tried to explain above, and we can't distinguish between promises and thenables, thus |
I guess I am really missing something, because for now, I only see circular reasoning here. I hope a sleep will help. |
Just in case, let me try to rephrase my most recent comment in a way that seems a bit less circular:
Ta-da! :) |
You lost me on [1] :) Too meta for you? Not to me, for now at least. |
Let’s take a step back and sleep on this. @rkatic is right that no valid promise implementation would call |
Now that I had my needed dose of rest, I have mixed feelings about this. I can agree that not allowing thenable fufilled values makes the usage more "natural" in some cases, eliminating a subtle but sometimes important distinction to the user - user don't have to bother to return However, as mentioned by @kriskowal, it can be an too strong assumption that other promise implementations will never have thenable fulfilled values. Also, I am not sure that we can even consider this an edge case. |
Per discussion at #205, I suppose this one can be closed. |
Actually, since #205 is rejected, and acknowledging that fulfilled values can be thenables, this issue seams more relevant then before. |
Let's take a different approach. Can you show us why this would be beneficial by including a test that (a) does not currently pass; and (b) is not about a cyclic promise chain (i.e. a promise resolving to itself)? "should propagate fulfilled value as it is" currently passes, without your code modifications. "should coerce thenables which resoved value is also thenable" is actually about promise cycles, which is covered by #223. |
@domenic Both tests that I added do not currently pass. Not completely sure what you mean with "not a cyclic promise chain", but the second added test should not be one of those. |
Oh, sorry for the wrong assumption then. The fact that "should propagate fulfilled value as it is" doesn't pass seems worrying and is a convincing argument. I'll try to look into it. Thanks for your persistence. |
Are you ok with removing changes regarding coercing? Would it make this pull-request more acceptable? |
I think we're going to wait until the Promises/A+ test suite 1.1 is done, which contains tests to ensure that returned thenable-for-thenable chains are flattened. Q already passes those, but having them in place will prevent regressions from pull requests like this. Then we can investigate how to make the tests you included pass. I should be done with the test suite by this weekend, most likely. |
Because of the recursive assimilation algorithm in Promises/A+ 1.1, preventing resolution to stuck in every situations is not simple, if not impossible (depends on how badly the thenable |
It looks like we'll be settling on a variant of AP2 (see http://wiki.ecmascript.org/lib/exe/fetch.php?id=strawman%3Apromises&media=strawman:promisesvsmonads2.pdf ). But don't change Q or Promises/A+ yet. This should all be decided at the end-of-July TC39 meeting. When we have a decent draft of this AP2 variant, I'll post a pointer here and on Promises/A+ and invite comments. |
FWIW Promises/A+ 1.1 is wrapping up soon, so my strategy of waiting until we have those tests in place, then trying to merge this because it contains some tests-that-fail-but-probably-shouldn't, still seems like the way to go. |
Reminder. The ink is drying on the ES6 promise specification. Let’s note the decisions here and wrap it up. |
Fulfilled value should be propagated as-it-is even if it is a thenable.