-
-
Notifications
You must be signed in to change notification settings - Fork 646
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
Consider adding "finally" #3335
Comments
+1 I've found myself wanting this construct from time to time. |
That would indeed be awesome. We can allow it on all platforms. For platforms that don't support it natively, it's just a matter of calling / performing a goto to the finally function both inside the catch handler as before any block termination (e.g. return) |
There are some funny cases like finally in a loop that has continue. You have to goto the finally, then back up to the loop condition. Unless I'm misunderstanding how finally works. |
Yes, anything that breaks the flow to out of the try block must go through finally - including break or continue. But it may be a matter of adding the finally function call before each of those statements |
I'm pretty sure that should execute the finally block, but not the otherStuff. |
Yes. Here's how I'd transform it: while(cond) {
function finallyBlock() {}
try {
finallyBlock();
continue;
}
catch(_:Dynamic) {
finallyBlock();
throw _; //rethrow when supported
}
otherStuff;
} |
What if the finally block has a |
We could forbid it ;) . I mean - we could deal with that, but it might start to get a little messy. |
Java actually inlines the |
I don't know, finally is not really compatible with my control flow aesthetics... :( |
Yes I don't like it either from a language design point of view, it has too much flows: return is clearly an undefined case for instance, it should even be forbidden at compilation. But what if a throw is made in a catch, the order of finally/catches etc. It's very ambiguous. I wonder what we could come up that would work better. For instance if you use a "rethrow" in a catch, we use finally to implement it. |
Finally would get called in this case even if no exception is caught |
From what I gather the rule is "if control flow leaves the try block (by whatever means), execute the finally block. If control flow reaches the end of the finally block, continue with what would have originally happened". |
I wonder why Instead of Scope Exit in other languages: |
Finally is good for closing resources which is really all I use it for.
As an alternative Java has try-with-resources which is even nicer for this case imo. http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html Using similar to their syntax it could be:
|
Both of these are just narrow version of scope exit... ... which would be even harder to support across all targets, unless you duplicate code like a madman. Which incidentally you can already do with a macro. |
Actually if we forbid return/continue/break inside finally blocks, we can do it on all targets without code duplication. |
At the cost of a closure, which doesn't exactly help with the original stack trace problem I would imagine. |
I suggest add a new label syntax: {
beforeLabel1();
label1:
afterLabel1();
label2:
afterLabel2();
} A label should convert to a {
beforeLabel1();
label1({
afterLabel1();
label2(
afterLabel2()
);
});
}
|
For example, given the code below: {
var fd = File.write("file.txt");
MyMacro.scopeExit(fd.close()):
fd.writeString("Hello,");
fd.writeString("World!");
} , will convert to {
var fd = File.write("file.txt");
MyMacro.scopeExit(fd.close(), {
fd.writeString("Hello,");
fd.writeString("World!");
});
} |
The label syntax is a weak version of what |
Or we could use another symbol to avoid ambiguity with |
My idea is NOT to introduce a new feature or discuss scope exit syntax. I'm perfectly fine with the try/catch as it. We just want a way to keep the stack intact while still performing some exception recovery, which is not possible ATM. |
I think we could reuse
|
But |
Yes, but I don't want either finally or scope exit :) |
I don't know what should happen here. |
It need not be mixed with I don’t think it’s ambiguous, it’s just like @Simn has written above: "if control flow leaves the try block (by whatever means), execute the finally block. If control flow reaches the end of the finally block, continue with what would have originally happened”; and otherwise what would have happened is lost and the non-local exit from finally block is continued. I agree that In its basic form
becomes
but, as easily seen, this simple rewrite requires that In Haxe, macros can be used to remove this restriction by means of rewriting Adding |
@jacekszymanski one problem with "emulating" finally on platforms that don't support it is that unless they have some way to "rethrow" exceptions this will eat up the callstack, making it very hard to debug such exceptions... That's one of the main reasons holding me from adding finally as-it in Haxe syntax. |
For a start you could add support for finally to the languages that support it natively and also translate it as such:
I understand that Haxe wants to have 100% the same behavior on all platforms and that finally might be implemented differently on some languages. But considering the usage of finally, which is mostly resource-cleanup, it should not be a big deal. If issues are supported from the public, they can be investigated on demand. The other targets are a bit more tricky:
Can become...
...where the ScopeHelper destructor calls simply the lambda. This only works for simple cases where finally does not have return statements:
In a first version it could be unsupported to have return statements in the finally block to overcome this problem. Another solution to this topic might be to not support support finally, but only support something like the C# using-block or the Java try-block:
Focusing only on some dedicated resource-cleanup control-flows there might be simpler solutions than support any kind of finally-block. |
I know this potentially makes me a filthy hobo, but I really do like returning from a function in the |
Another thing that should be discussed as part of Haxe Evolution process. |
Up to know I was not a big fan of "finally". I find it complexify a bit too much try/catch while not bringing something that can't be done in a more standard way.
However I found that finally allows to have some cleanup code while preserving the full stack trace for the exception (tested in Chrome/JS), which is something right know we only support in Neko with neko.Lib.rethrow.
I wonder if we should either add finally as-it or use it to implement some kind of "rethrow" function on all platforms.
The text was updated successfully, but these errors were encountered: