-
Notifications
You must be signed in to change notification settings - Fork 376
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
Promise equality #211
Comments
I do get the confusion, but |
The problem is that resolution timing is inherently a side-effect. In any pure monad, we'd expect const ma = f();
const mb = g().chain(() => ma); and const mb = g().chain(() => f()); to have the same result |
Maybe it should say that then, because that covers all edge cases. If you don't think it does then you need to read more. |
What if we remove that line? If we say |
Well, my point is that just seeing the outcomes is really not enough to know if they are truly the same. To do that you'd have to know both the outcome and the time of resolution.
Then I think I'd be better to just say that Promises aren't monads because they don't satisfy the laws instead of adopting an IMO too loose sense of equality. I think that is a great idea. It's completely general. However, the current text does already talk about referential transparency even though it doesn't use the term directly:
|
I don't think it's important if they're referential transparent. It might help understand more about why it concerns you if they are equal, what's the use case?
We should. |
They're not referential transparent if they resolve at different times. I can easily tell the difference by calling
There is no use case 😄 I just read that part of the readme and found the definition misleading. A promise isn't isomorphic to the value it resolves to and thus it can't be compared for equality just by comparing the value it resolves to. |
That's what I mean, if that's not what you mean, then ... erm... |
These two promise resolves to the same value: const a = new Promise((res) => setTimeout(() => res("Tada"), 6000));
const b = new Promise((res) => setTimeout(() => res("Tada"), 1000)); Are they equal? No, because the value that the promise const c = a.then((_) => Date.now()); I.e. there is an observable difference between |
Side effects inside none-pure code. Those are not referential transparent so aren't equal. |
Excellent talk about it here : https://www.youtube.com/watch?v=qBvFsA3dglk |
Just to add two cents, I think with all these equality definitions it's really depends on what we've chosen to care about in a particular case. And the example with promises is valid, if we don't care about time spend (when we need it to only resolve eventually with a particular value). Also example with Or we can argue that const a = [1]
const b = [1]
const map = new Map()
map.set(a, 1)
map.set(b, 2)
map.get(a) + 1 // if we replace `a` with `b` this expression will have different result So it always depends on what we care about, and in my opinion example with Promises is good enough. |
Let me phrase my argument from another angle. Are two In general two monadic values are only equal if they contain the same value and represent the same effects. Promises are the same. When talking about their equality we have to consider their effects which is their resolution/rejection time. |
Maybe it's enough for the readme to say that those are example interpretations of equivalence and not definitions for all data types. I don't think the intent is to have an authoritative source for what constitutes equivalence. Rather I think the intent is to provide a couple of examples to spur intuition. I'm sure you could take exception to any of them if you tried hard enough. For instance, the function example could be picked apart as well. const foo = x => { const _ = R.range(1, 1000); return x; } Is |
So perhaps this is a better example to illustrate that promises are not referentially transparent even if they evaluate to the same value. const a1 = // promise that resolves to "a" after 2 minutes
const a2 = // promise that resolves to "a" after 4 minutes
const b = // promise that resolves to "b" after 3 minutes
const expr1 = Promise.race([a1, b]); // resolves to "a"
const expr2 = Promise.race([a2, b]); // resolves to "b" If Anyway, sorry for commenting on an old issue. #288 reminded me of it 😅 |
The readme says:
Is this really an "appropriate definition of equivalence for the given value"? Because then I don't understand what the criteria for equivalence is?
It seems to me that a promise that resolves in five minutes with the value "Tada" is not equal to a promise that resolves tomorrow afternoon with the value "Tada". I'd say that two promises are only equal if they resolve to equivalent values at the exact same times.
The text was updated successfully, but these errors were encountered: