Skip to content
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

Integration with "third state" thinking #4

Open
domenic opened this issue Feb 10, 2016 · 6 comments
Open

Integration with "third state" thinking #4

domenic opened this issue Feb 10, 2016 · 6 comments

Comments

@domenic
Copy link

domenic commented Feb 10, 2016

I wrote up why I think cancelation should be a third state: https://github.com/domenic/cancelable-promise/blob/master/Third%20State.md

I wanted to use this issue to document the tweaks to your cancelation tokens I'd envision to be compatible with that. They are small:

  • Rename CancelError to CancelReason; part of the whole third-state philosophy is that cancelations are not errors. This also avoids the awkwardness of ct.promise fulfilling with an error, which is weird.
  • Rename throwIfRequested to cancelIfRequested, and have it synchronously do a throw cancel instead of a plain throw. Also, maybe it should accept an argument for the cancelation reason?

I think that's it. I'm not saying you should necessarily change the document (unless you definitely agree with me on third state, and want to tie the proposals together) but wanted to open the issue to make sure it was discussed.

@zenparsing
Copy link
Owner

I read the document - very interesting!

I must admit that the idea of adding a catch cancel clause makes me a little nervous, though. As a thought experiment: it seems like a cancel completion is like a throw, except that it's not catchable by our unconditional catch clause (which is all that we have right now). Now, what if we had:

  • A conditional catch clause of the form catch (x : SomeErrorType) {} (suspend disbelief on the syntax and semantics for now).
  • A new symbol-keyed flag named @@catchExplicit.

The semantics of the unconditional catch clause could then be modified so that it only catches exceptions if error[@@catchExplicit] is falsey. We could set CancelError.prototype[@@catchExplicit] to true, so that the only way to catch it would be to add an explicit handler for it.

try {
    throw new CancelError("humbug");
} catch (x) {
    // Not caught here
}
try {
    throw new CancelError("humbug");
} catch (x : CancelError) {
    // But it is caught here
}

This doesn't have the properties that you're looking for for promises, though, since the rejection handler would still (presumably) be called in such a situation. Also, a catch-all that doesn't catch something is really surprising!

@domenic
Copy link
Author

domenic commented Feb 10, 2016

Yeah. I agree it's a bit unsettling to invent a new parallel thing that shares so many of the semantics with throw completions. That is probably why typed catch is attractive. But I think there are a number of reasons why an approach like you suggest is suboptimal:

  • It perpetuates the category error by calling them both exceptions (exceptional error conditions), and saying that cancelations are just a subset of exceptions.
  • It presents the opportunity for other uncatchable exceptions to arise. This takes us down the path of a very different error model than JavaScript or its predecessors have.
  • Perhaps most important of all is what happens when these reach the top level, uncaught. With cancelations, nothing should happen. But with exceptions, they should be reported.
  • Finally, it ties progress on cancelation to progress on catch guards, which are delayed until progress on pattern matching appears. That seems like a multi-year project.

I really think that although they share similar mechanisms in terms of how they bubble, cancelations and exceptions are distinct. We shouldn't let their implementation-sameness cause us to conflate the two concepts.

@benjamingr
Copy link

I think the third state document is important, I'm writing a lot of cancellation aware code in C# and cancellation-as-exceptions is quite the annoyance for me.

@wycats
Copy link

wycats commented Jun 4, 2016

I agree with Domenic on "third state" thinking, and this particular point seemed (perhaps surprisingly?) uncontroversial at TC39.

@Zamralik
Copy link

@domenic cancelIfRequested shouldn't accept a reason parameter. The reason should be given when requesting the cancellation. cancelIfRequested is just a "break point" for where cancellation can occur.

const token = new CancelToken(
    (cancel) => {
        setTimeout( () => { cancel("Timeout"); }, 5000 );
    }
);
task(token);

@benjamingr
Copy link

@Kulvar this is a 2016 issue, cancel tokens are dead, third state is dead, we might revive them for Node (and the web platform has AbortController). Sorry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants