Try / Catch proposal

已查看 106 次
跳至第一个未读帖子

Felipe

未读,
2015年8月20日 17:32:002015/8/20
收件人 Dart Misc
I would like to do this in Dart. 

Now:

void myFunction(){
 
try {
   
....
 
} catch (e) {
   
....
 
}finally{
   
....
  }
}


Proposal (I think for many situations is cleaner)

void myFunction(){
   
....
} catch(e){
   
....
} finally{
   
....
}


Thanks ;)

Cristian Garcia

未读,
2015年8月20日 19:12:012015/8/20
收件人 Dart Misc

+1 Nice!


--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.

Cristian Garcia

未读,
2015年8月20日 19:58:472015/8/20
收件人 Dart Misc

Should this only apply to "actions" (void functions)?

Felipe

未读,
2015年8月20日 22:33:522015/8/20
收件人 Dart Misc
To functions and methods, void or not. It was just one example. 

Lasse R.H. Nielsen

未读,
2015年8月21日 03:41:592015/8/21
收件人 mi...@dartlang.org
When I see a specific feature like this, I try to see if it generalizes. Whether it does or not tend to be enlightening :)

What if *any* block could have a catch/finally. 

It sounds more general ... but it turns  out, all that all it does is to remove the "try" from a try/catch/finally statement. It may be slightly shorter, but lacks the leading hint that something is wrapping the following block (all special blocks have leading syntax, "for", "while", "do", "try", "catch", "finally").
Uniquely among these, the "try" actually isn't necessary (the "do" is because otherwise {stmts} while (expr); would be a block statement followed by an empty while).

A function body isn't *exactly* a block statement, but it's close enough that if we remove "try" and make "catch/finally" a possible suffix of a block statement, it could generalize to function bodies.

So what would we lose?
One thing is that the entirety of a function's body is no longer inside an outer block. That means parser complications - the "catch(e)" after a method must not be seen as a new function declaration. Since "catch" is a reserved word, that's probably not a problem.
It will be slightly harder to read for people trained to find the matching "}" and assume the function ends there (and ditto tools).

What is the variable scope of those extra blocks? It would be reasonable that they are in scope of the function parameters. So far a "(var x) { stmts; }" has only had the scope of "x" extend to the following block. It's not a big problem to have it also extend to more blocks, but it is a slight idiosyncrasy that might trip people up.

So, all in all, it adds a bunch of small differences from other languages and other parts of Dart in order to save "{ try" and "}" (and some whitespace).
I'm not sure it's actually worth it (even if I personally think "try" is ugly and annoying). If anything, I'd remove the need for "try" inside the function, and still require you to wrap it in an outer "{" and "}" body delimiter.


/L


--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--
Lasse R.H. Nielsen - l...@google.com  
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K - Denmark - CVR nr. 28 86 69 84

ravi teja

未读,
2015年8月21日 03:57:492015/8/21
收件人 mi...@dartlang.org
For:

1) It removes annoying indentation caused by try/catch. This point only matters for complex functions. When you have too many indentations and you split the screen, using the horizontal scroll bar could be very annoying.

Against:

1) It would be weird to have access to variables from main block in catch and finally blocks. To people who are familiar with C-like languages, only variables from current scope and scopes above could be used. This looks like it gives access to sibling scopes.


Bob Nystrom

未读,
2015年8月21日 12:49:422015/8/21
收件人 General Dart Discussion
On Fri, Aug 21, 2015 at 12:41 AM, 'Lasse R.H. Nielsen' via Dart Misc <mi...@dartlang.org> wrote:
When I see a specific feature like this, I try to see if it generalizes. Whether it does or not tend to be enlightening :)

What if *any* block could have a catch/finally. 

This is how Ruby works. There is no "try" form. Instead, you can add a rescue clause to any block form. I think even class definitions allow it since they contain imperative code.
 

It sounds more general ... but it turns  out, all that all it does is to remove the "try" from a try/catch/finally statement. It may be slightly shorter, but lacks the leading hint that something is wrapping the following block (all special blocks have leading syntax, "for", "while", "do", "try", "catch", "finally").

Well, block statements don't have a leading keyword. :)

I think the idea is to not think of it as wrapping the following block but as being a property of the block itself.
 
A function body isn't *exactly* a block statement, but it's close enough that if we remove "try" and make "catch/finally" a possible suffix of a block statement, it could generalize to function bodies.

So what would we lose?
One thing is that the entirety of a function's body is no longer inside an outer block. That means parser complications - the "catch(e)" after a method must not be seen as a new function declaration. Since "catch" is a reserved word, that's probably not a problem.

The spooky one is our funny catch syntax where you can omit the catch clause:

foo() {
  ...
} on Bar {
  ...
}

I can't come up with any actual ambiguity, but it's close enough (this almost defines a second function Bar that returns an on) to make me worried about later language additions.
 
It will be slightly harder to read for people trained to find the matching "}" and assume the function ends there (and ditto tools).

What is the variable scope of those extra blocks? It would be reasonable that they are in scope of the function parameters. So far a "(var x) { stmts; }" has only had the scope of "x" extend to the following block. It's not a big problem to have it also extend to more blocks, but it is a slight idiosyncrasy that might trip people up.

So, all in all, it adds a bunch of small differences from other languages and other parts of Dart in order to save "{ try" and "}" (and some whitespace).
I'm not sure it's actually worth it (even if I personally think "try" is ugly and annoying). If anything, I'd remove the need for "try" inside the function, and still require you to wrap it in an outer "{" and "}" body delimiter.

From the purist standpoint, I like the idea of allowing any block (or member body) to have a catch clause and remove the special try construct.

In practice, though:
  • try blocks aren't actually that common. Exceptions are thrown far more often than they are caught. (The majority of exceptions are programmatic errors whose intent is to kill the program with a helpful stack trace.)

  • Users coming from C++, Java, C#, and JS are familiar with a try form.
Given those, I don't think this is the best place for Dart to try to innovate.

Cheers!


tatumizer-v0.2

未读,
2015年8月21日 14:49:272015/8/21
收件人 Dart Misc
There's one area where innovation won't hurt: adding context to exceptions. Very often, exception is caught just to wrap it in another exception (with more context information) and then re-throw. This is ugly. Instead, it would be nice to have something like a function
onException((e)=>e.addContext("user $userName");
(naturally, when function(block) exits, all onException() handlers are cleaned up automatically)

Currently, this is a major use case for "catch" Whoever doesn't want to add catch to every function, adds a lot of logging instead. Some do both. Program quickly becomes unreadable. Log files are getting huge and require special tools to make any sense of them - though most of the time, you need detailed info only if exception occurs.

P.S. Probably, this thing can be generalized to cover more use cases. E.g.
onReturn((v)=>print("returning $v from foo");  // triggered on normal return
This covers common use case when you have multiple return statements in a program, and want to print returned value for debugging, so you need to add "print" in several places.

 




Andreas Kirsch

未读,
2015年8月21日 15:15:532015/8/21
收件人 General Dart Discussion

I have to say it's a very rare habit to catch, augment and rethrow. :(
AngularDart doesn't do that really, and neither does our code usually. I wish it was easier or more prominent, since it would help the general debugging user story a lot :) especially, since stacktraces don't provide parameter information or similar in dart.

Cheers,
Andreas

tatumizer-v0.2

未读,
2015年8月21日 15:35:202015/8/21
收件人 Dart Misc
> I have to say it's a very rare habit to catch, augment and rethrow. :(
Depending on where you sit, the world can look completely different. I work with production server-side code all the time (not necessarily code written by myself). There's so much logging and catch/rethrow, you can't see the forest for the trees (in fact, sometimes there's no forest at all, but it's a different story).

On a system level, it's like you say - no help at all. Exceptions thrown by system code most often don't have any context information - burden is put on application, which adds even more bloat to already bloated application code.



Felipe

未读,
2015年8月22日 10:45:562015/8/22
收件人 Dart Misc
Thanks guys for your detailed answers.

Lasse, I do not know if from the technical point of view (parser) is a complication but from a more abstract and ideal perspective I liked the idea. Maybe today analyzing the cost / benefit ratio is not viable.

Sorry for my English, it is very bad and I can hardly express myself (I'm using google translate;-)).

Thank you

- Felipe
回复全部
回复作者
转发
0 个新帖子