Closed bergus closed 8 years ago
I am happy with else as the name. JavaScript and Python are different enough that people should be able to figure out what code they are reading.
I'm on board with the "third state" use case and like the thrown Cancel object and more regular syntax proposal, but the semantics of else
now feel slightly more opportunistic than necessary to me. I'd like to come at it from the perspective that if there's not an alternative that works both lexically and semantically then it might be better for the language to avoid forcing the matter.
I remarked in another issue how cancellation is like a deferred condition which makes try { ... } else { ... }
appealing, but #24 raised the necessary point that introducing a new exit path from the try block could break legacy code that puts compensating logic in the catch block. Lexically, else
is great as a handler block keyword since there's no way it will conflict with existing code, but flipping the error case onto it since the cancel case doesn't work out doesn't feel like a first class acknowledgement of all the possible states.
try {
...
} catch (e) {
if (e instanceof Cancel) {
// handle cancel only
} else {
// handle error only
}
}
vs.
try {
...
} cancel (c) {
// handle cancel only
} error (e) {
// handle error only
}
vs.
try {
...
} else (e) {
// handle error only
}
The first example will work with just the new thrown Cancel
. The second, unfortunately, isn't possible because we can't introduce new keywords arbitrarily. The third is convenient for the case it handles, but it's lopsided and possibly risky by comparison. People who naively start substituting "else" as the new "catch" could open themselves to similar unplanned path risks as omitting thrown Cancel
s from catch would have.
The latest draft distinguishes between catch as the exception handler and else as the error handler, which is an excellent way of framing it. But "cancel", the third state, is arguably just as much of an "else" to the try as an error is. So, while we're at it, why not try { ... } default { ... }
for cancellations? I ask that tongue-in-cheek to make the point that at some point plucking sort-of-related keywords for their sugaring benefit can drift into territory that complicates the language. I'm not saying that else
for errors is completely unacceptable...but since this maps onto Promise syntax as well, then the threshold for introduction may very well be higher than if it was just being evaluated for JavaScript.
Reopening since at TC39 it was pointed out that (as long as we are careful and don't allow catch
at the same time) we can use any word.
I do not want to discuss adding a cancel-specific handler, as @nlwillia does in his tome; I think handling cancelations should be rare, and since we cannot do third state any more, it doesn't make sense as a primitive. Open a separate issue if you disagree.
Some possibilities (see Wikipedia):
except
(precedent Python). I would have to rewrite all the documentation that talks about "exceptions that are not errors"; maybe the new line would be "thrown values that are not exceptional" or something.recover
(precedent Scala, sort of).rescue
(precedent Ruby).I like except
and recover
personally. Twitter poll, tell your friends
What about error
? It emphasizes the distinction between exceptions (all possible throwables) and errors (a specific type of throwable). ex: Bluebird
Yeah, that's a good possibility as well. I'm surprised no other language has included it.
I like except
, it also emphasises that cancellation is not exceptional.
Regarding the cancel-specific handler, I did open #36.
If I understand correctly, is the idea that the new clause should essentially replace "catch" for most if not all exception handling use cases?
Yep.
If I introduce cancellation into an existing codebase, does that mean that I need should update catch-sites to use the new clause instead?
Yes. @littledan thought that would be better than automatically allowing the existing program to adapt. I disagree, but it was a hard requirement from him and others on the V8 team.
Depending on whether you want them to catch cancellations, yes. The default (non-updated) is to treat them as exceptions ("Help, something happened so I don't get my results back, I need to do something about that").
Would it be true statement to say that the only way to model cancellation, currently, is by rejecting/throwing?
I'm not sure exactly what you mean. You mean, without this proposal? There are other models, e.g. the one Bluebird uses (where cancelation does not trigger .catch() but does trigger .finally(); this even transfers into the syntactic space if you use function*/yield, but not if you use async/await).
@domenic Bluebirds approach could even transfer to the syntactic space of async
/await
if you consider a conditional return
statement to be hidden in every await
that is "tagged with" a cancellation token (via await.cancelToken
or a similar mechanism).
we can't introduce new keywords arbitrarily
I hear this a lot but, as far as I know, promises/async processes are really big in javascript and its one of the key differentiators from other (compiled) languages. Because of that, i think its okay for javascript to introduce new keywords in regards to its promises/async functionality because this particular functionality is already different to begin with.
@domenic I don't want to phrase the point of view on catch
semantics changing as a "hard requirement from the V8 team" but it's a concern we are raising as participants in the design process. You were previously able to intercept all non-local control flow with catch
, and now you wouldn't be. This also affects existing uses of Promises in an analogous way--you can be sure that one of the two callbacks passed to Promise.prototype.then
would be reached. I like the compromise of using a different block form to filter cancels.
because in Python it has quite the opposite meaning: it runs when there was no exception.
is literally equivalent to
I see that your proposal does not allow
try
-catch
-else
but onlytry
-else
(which Python does not have), but I believe it's still a concern and we should try to come up with something more fitting.