D - The case against a 'throws' statement
- Walter (71/71) Sep 01 2001 I've been discussing this in email with Bruce Eckel, who managed to expr...
- Dan Hursh (55/136) Sep 02 2001 Well, I think I'll give my last argument on the topic and let it go. I
- Dan Hursh (25/164) Sep 02 2001 Yes, I know I said that would be last post on this topic, but I want to
- Axel Kittenberger (31/31) Sep 02 2001 I don't agree that unchecked exceptions like in C++ are better than in
- kaffiene (9/9) Sep 02 2001 This is a choice between D being a language to create large, stable, cor...
- kaffiene (7/15) Sep 02 2001 It is not an untested assumption. It might have been many years ago Jav...
- John Carney (29/43) Sep 02 2001 that
- Kent Sandvik (9/9) Sep 06 2001 Long time ago I wrote code that tried to go around error handlings by
- Walter (5/14) Sep 06 2001 I've had a long standing disagreement with some people who think that
- Russ Lewis (18/18) Sep 02 2001 It's an intriguing and disturbing argument. I think I would say that if...
- Russ Lewis (3/8) Sep 02 2001 Maybe with the "hack switch" on, it would still check things, but they w...
- Dan Hursh (17/23) Sep 02 2001 You can get idiots in any language. If you find a language feature
- Axel Kittenberger (10/14) Sep 02 2001 No it can, writing 'throws' in the decleration is not alone making the
- Walter (12/15) Sep 02 2001 It's common for C and C++ code to crash because the code failed to test ...
- Axel Kittenberger (29/37) Sep 03 2001 Well I used MSVC in the past, an the application just halted with an exi...
- Dan Hursh (29/71) Sep 03 2001 I believe I've mention in one of the other "exceptions" threads that I
- Axel Kittenberger (37/47) Sep 03 2001 Absolutly not, Most times I either forget about it, or are to lazy, or
- Dan Hursh (7/31) Sep 04 2001 Sorry. For some reason the whole scenario about the nuke plant came to
- Dan Hursh (64/80) Sep 02 2001 This is were we differ then. I do believe a function should be able to
- Axel Kittenberger (19/42) Sep 03 2001 I don't think this will benefit in the matter of readability. Why should...
- Dan Hursh (47/74) Sep 03 2001 This is a concession to the fact that some venders will implement
- Axel Kittenberger (6/13) Sep 03 2001 That's the point, and thats a principle decision languages have to do. F...
- Dan Hursh (8/24) Sep 03 2001 True. I was just going off some of his comments I've seen on this
- Axel Kittenberger (2/3) Sep 03 2001 Sorry if I was importunate/stolid :/
- Walter (7/87) Sep 03 2001 base
- Russ Lewis (13/21) Sep 04 2001 Absolutely. I didn't mean to imply that having non-strict throws clause...
I've been discussing this in email with Bruce Eckel, who managed to express the ideas in writing much better than I have (I guess that's why Bruce is a successful professional writer!). Here are his comments on it, reproduced with his kind permission: --------------------------------------------------------------------- It's like strong static type checking vs late weak typing; the former sounds like a really good idea, but in practice it turns out that as long as type checking happens, you're OK, and late weak typing allows faster experiments or something like that. The way I (now) see exceptions is something like this: 1) The great value of exceptions is the unification of error reporting: a standard mechanism by which to report errors, rather than the popourri of ignorable approaches that we had in C (and thus, C++, which only adds exceptions to the mix, and doesn't make it the exclusive approach). The big advantage Java has over C++ is that exceptions are the only way to report errors. 2) "Ignorable" in the previous paragraph is the other issue. The theory is that if the compiler forces the programmer to either handle the exception or pass it on in an exception specification, then the programmer's attention will always be brought back to the possibility of errors and they will thus properly take care of them. I think the problem is that this is an untested assumption we're making as language designers that falls into the field of psychology. My theory is that when someone is trying to do something and you are constantly prodding them with annoyances, they will use the quickest device available to make those annoyances go away so they can get their thing done, perhaps assuming they'll go back and take out the device later. I discovered I had done this in the first edition of Thinking in Java: ... } catch (SomeKindOfException e) {} And then more or less forgot it until the rewrite. How many people thought this was a good example and followed it? Martin Fowler began seeing the same kind of code, and realized people were stubbing out exceptions and then they were disappearing. The overhead of checked exceptions was having the opposite effect of what was intended, something that can happen when you experiment (and I now believe that checked exceptions were an experiment based on what someone thought was a good idea, and which I believed was a good idea until recently). When I started using Python, all the exceptions appeared, none were accidentally "disappeared." If you *want* to catch an exception, you can, but you aren't forced to write reams of code all the time just to be passing the exceptions around. They go up to where you want to catch them, or they go all the way out if you forget (and thus they remind you) but they don't vanish, which is the worst of all possible cases. I now believe that checked exceptions encourage people to make them vanish. Plus they make much less readable code. In the end, I think we must realize the experimental nature of exceptions and look at them carefully before assuming that everything about exceptions in Java are good. I believe that having a single mechanism for handling errors is excellent, and I believe that using a separate channel (the exception handling mechanism) for moving the exceptions around is good. But I do remember one of the early arguments for exception handling in C++ was that it would allow the programmer to separate the sections of code where you just wanted to get work done from the sections where you handled errors, and it seems to me that checked exceptions do not do this; instead, they tend to intrude (a lot) into your "normal working code" and thus are a step backwards. My experience with Python exceptions supports this, and unless I get turned around on this issue I intend to put a lot more RuntimeExceptions into my Java code.
Sep 01 2001
Well, I think I'll give my last argument on the topic and let it go. I do agree that exception specifications can be a problem when the compiler is constantly throwing them in you face when you are not ready to deal with error conditions yet. On the other hand I'd still like a mechanism to see if there any exceptions that go uncaught before I send something out the door. Let's face it: it is possible to check this at compile time provided that a 'throws' is allowed. If you allow it, but not require it, then becomes like the rest of the programming by contract facilities provided by D. To get the behavior that will allow you to forget it, you have to make the lack of a throws clause the equivalent of saying you can throw any valid exception type. Given that, the compiler will only give you an exception specification error if you put a throws clause on a function. But by putting the throws clause on the function you are declaring that you want to deal with any uncaught exceptions that you didn't say you throw. In other words, if it's harassing you, it's because you asked for it. If you make it any more strict, then exception specifications will be an annoyance. Anything less, and it will be no more possible to know you are shipping something that won't throw exceptions in the user's face than you could be sure the C equivalent would behave in a remotely robust fashion. Where I work the users have become intimately familiar with Java exceptions because the developers went the route of declaring all mains as being able to throw any exception. I've found end user dislike java stack dumps even more than they hate "segment violation"s and "bus error"s. Exceptions tend not to mean anything to end users or admins. They are great however for developers. By having the ability to declare throws clauses, but not requiring them, those who wish to ignore them at compile time and deal at run time instead can do so. Those who wish to control which exceptions if any will make it to the user will have the tools to do so. It would be a courtesy to the developer who likes the handle exceptions in code if library developers would provide reasonable throws clauses to API functions. This still would not require the users of the API to catch the exceptions, but would advertise the possible exceptions that can occur within the API and provide the necessary tools to those who would like to know they've handle everything. Without a throws clause, the only way you can be sure you've caught everything is to have all the source available (not a bad thing, but not always possible) and use a lint-like tool to tell you what you've missed. Even with the compromise I'm suggesting, it might still be nice (though probably not necessary) to have a tool that can scan a compilation unit for functions that don't have an explicit throws clause. In closing, Bruce is right in that if you throw exceptions in the developers face from square one, they will silently get lost by inducing bad coding techniques. However, if D is truly for "Programmers who routinely use lint or similar code analysis tools to eliminate bugs before the code is even compiled", "People who compile with maximum warning levels turned on and who instruct the compiler to treat warnings as errors" and "Programming managers who are forced to rely on C programming style guidelines to avoid common C bugs" then I don't see how D can deliver that with out some form of support for making sure the no unexpected exceptions can sneak through. Dan Walter wrote:I've been discussing this in email with Bruce Eckel, who managed to express the ideas in writing much better than I have (I guess that's why Bruce is a successful professional writer!). Here are his comments on it, reproduced with his kind permission: --------------------------------------------------------------------- It's like strong static type checking vs late weak typing; the former sounds like a really good idea, but in practice it turns out that as long as type checking happens, you're OK, and late weak typing allows faster experiments or something like that. The way I (now) see exceptions is something like this: 1) The great value of exceptions is the unification of error reporting: a standard mechanism by which to report errors, rather than the popourri of ignorable approaches that we had in C (and thus, C++, which only adds exceptions to the mix, and doesn't make it the exclusive approach). The big advantage Java has over C++ is that exceptions are the only way to report errors. 2) "Ignorable" in the previous paragraph is the other issue. The theory is that if the compiler forces the programmer to either handle the exception or pass it on in an exception specification, then the programmer's attention will always be brought back to the possibility of errors and they will thus properly take care of them. I think the problem is that this is an untested assumption we're making as language designers that falls into the field of psychology. My theory is that when someone is trying to do something and you are constantly prodding them with annoyances, they will use the quickest device available to make those annoyances go away so they can get their thing done, perhaps assuming they'll go back and take out the device later. I discovered I had done this in the first edition of Thinking in Java: ... } catch (SomeKindOfException e) {} And then more or less forgot it until the rewrite. How many people thought this was a good example and followed it? Martin Fowler began seeing the same kind of code, and realized people were stubbing out exceptions and then they were disappearing. The overhead of checked exceptions was having the opposite effect of what was intended, something that can happen when you experiment (and I now believe that checked exceptions were an experiment based on what someone thought was a good idea, and which I believed was a good idea until recently). When I started using Python, all the exceptions appeared, none were accidentally "disappeared." If you *want* to catch an exception, you can, but you aren't forced to write reams of code all the time just to be passing the exceptions around. They go up to where you want to catch them, or they go all the way out if you forget (and thus they remind you) but they don't vanish, which is the worst of all possible cases. I now believe that checked exceptions encourage people to make them vanish. Plus they make much less readable code. In the end, I think we must realize the experimental nature of exceptions and look at them carefully before assuming that everything about exceptions in Java are good. I believe that having a single mechanism for handling errors is excellent, and I believe that using a separate channel (the exception handling mechanism) for moving the exceptions around is good. But I do remember one of the early arguments for exception handling in C++ was that it would allow the programmer to separate the sections of code where you just wanted to get work done from the sections where you handled errors, and it seems to me that checked exceptions do not do this; instead, they tend to intrude (a lot) into your "normal working code" and thus are a step backwards. My experience with Python exceptions supports this, and unless I get turned around on this issue I intend to put a lot more RuntimeExceptions into my Java code.
Sep 02 2001
Yes, I know I said that would be last post on this topic, but I want to deal with one ambiguity I'm my argument. Along with everything below, I would also say that you would need to allow a function to declare a throws clause that contains exceptions that are bases classes of one or more of the exceptions he may actually throw, and a function must be able to declare that it can throw exceptions that it in fact does not. Also, a catch statement must be able to catch derived types if there isn't an exact match. This will allow for an API standard to declare that there are certain exception that could be thrown and the programmers should be ready to handle. If a specific implementation of a standard wants to make more granular error checking possible by subclassing the exceptions of the standard API, it would still work for someone programming to the standard and it would allow someone to leverage the more granular error handling for a platform if they so choose. This will also allow an implementation to write code robust enough that it will not need to throw one or more of the exceptions declared by the standard without having an adverse affect on the programmers who code to the standard. Coding to a standard should never flag and error or warning. Writing a more robust implementation should not flag an error either. I think that's everything. I may add more amendments to this, but I hope not. Dan Dan Hursh wrote:Well, I think I'll give my last argument on the topic and let it go. I do agree that exception specifications can be a problem when the compiler is constantly throwing them in you face when you are not ready to deal with error conditions yet. On the other hand I'd still like a mechanism to see if there any exceptions that go uncaught before I send something out the door. Let's face it: it is possible to check this at compile time provided that a 'throws' is allowed. If you allow it, but not require it, then becomes like the rest of the programming by contract facilities provided by D. To get the behavior that will allow you to forget it, you have to make the lack of a throws clause the equivalent of saying you can throw any valid exception type. Given that, the compiler will only give you an exception specification error if you put a throws clause on a function. But by putting the throws clause on the function you are declaring that you want to deal with any uncaught exceptions that you didn't say you throw. In other words, if it's harassing you, it's because you asked for it. If you make it any more strict, then exception specifications will be an annoyance. Anything less, and it will be no more possible to know you are shipping something that won't throw exceptions in the user's face than you could be sure the C equivalent would behave in a remotely robust fashion. Where I work the users have become intimately familiar with Java exceptions because the developers went the route of declaring all mains as being able to throw any exception. I've found end user dislike java stack dumps even more than they hate "segment violation"s and "bus error"s. Exceptions tend not to mean anything to end users or admins. They are great however for developers. By having the ability to declare throws clauses, but not requiring them, those who wish to ignore them at compile time and deal at run time instead can do so. Those who wish to control which exceptions if any will make it to the user will have the tools to do so. It would be a courtesy to the developer who likes the handle exceptions in code if library developers would provide reasonable throws clauses to API functions. This still would not require the users of the API to catch the exceptions, but would advertise the possible exceptions that can occur within the API and provide the necessary tools to those who would like to know they've handle everything. Without a throws clause, the only way you can be sure you've caught everything is to have all the source available (not a bad thing, but not always possible) and use a lint-like tool to tell you what you've missed. Even with the compromise I'm suggesting, it might still be nice (though probably not necessary) to have a tool that can scan a compilation unit for functions that don't have an explicit throws clause. In closing, Bruce is right in that if you throw exceptions in the developers face from square one, they will silently get lost by inducing bad coding techniques. However, if D is truly for "Programmers who routinely use lint or similar code analysis tools to eliminate bugs before the code is even compiled", "People who compile with maximum warning levels turned on and who instruct the compiler to treat warnings as errors" and "Programming managers who are forced to rely on C programming style guidelines to avoid common C bugs" then I don't see how D can deliver that with out some form of support for making sure the no unexpected exceptions can sneak through. Dan Walter wrote:I've been discussing this in email with Bruce Eckel, who managed to express the ideas in writing much better than I have (I guess that's why Bruce is a successful professional writer!). Here are his comments on it, reproduced with his kind permission: --------------------------------------------------------------------- It's like strong static type checking vs late weak typing; the former sounds like a really good idea, but in practice it turns out that as long as type checking happens, you're OK, and late weak typing allows faster experiments or something like that. The way I (now) see exceptions is something like this: 1) The great value of exceptions is the unification of error reporting: a standard mechanism by which to report errors, rather than the popourri of ignorable approaches that we had in C (and thus, C++, which only adds exceptions to the mix, and doesn't make it the exclusive approach). The big advantage Java has over C++ is that exceptions are the only way to report errors. 2) "Ignorable" in the previous paragraph is the other issue. The theory is that if the compiler forces the programmer to either handle the exception or pass it on in an exception specification, then the programmer's attention will always be brought back to the possibility of errors and they will thus properly take care of them. I think the problem is that this is an untested assumption we're making as language designers that falls into the field of psychology. My theory is that when someone is trying to do something and you are constantly prodding them with annoyances, they will use the quickest device available to make those annoyances go away so they can get their thing done, perhaps assuming they'll go back and take out the device later. I discovered I had done this in the first edition of Thinking in Java: ... } catch (SomeKindOfException e) {} And then more or less forgot it until the rewrite. How many people thought this was a good example and followed it? Martin Fowler began seeing the same kind of code, and realized people were stubbing out exceptions and then they were disappearing. The overhead of checked exceptions was having the opposite effect of what was intended, something that can happen when you experiment (and I now believe that checked exceptions were an experiment based on what someone thought was a good idea, and which I believed was a good idea until recently). When I started using Python, all the exceptions appeared, none were accidentally "disappeared." If you *want* to catch an exception, you can, but you aren't forced to write reams of code all the time just to be passing the exceptions around. They go up to where you want to catch them, or they go all the way out if you forget (and thus they remind you) but they don't vanish, which is the worst of all possible cases. I now believe that checked exceptions encourage people to make them vanish. Plus they make much less readable code. In the end, I think we must realize the experimental nature of exceptions and look at them carefully before assuming that everything about exceptions in Java are good. I believe that having a single mechanism for handling errors is excellent, and I believe that using a separate channel (the exception handling mechanism) for moving the exceptions around is good. But I do remember one of the early arguments for exception handling in C++ was that it would allow the programmer to separate the sections of code where you just wanted to get work done from the sections where you handled errors, and it seems to me that checked exceptions do not do this; instead, they tend to intrude (a lot) into your "normal working code" and thus are a step backwards. My experience with Python exceptions supports this, and unless I get turned around on this issue I intend to put a lot more RuntimeExceptions into my Java code.
Sep 02 2001
I don't agree that unchecked exceptions like in C++ are better than in checked once in java, yes the java ones tend to let you write ignorance code like 'catch Error {}' to ignore everything while you're experimenting. But the other side C++ allowing you just silently to bypass exceptions can also be even more nasty, if you want to write robust code you'll have to constantly check the API specifications in the fear you could miss an exception, and when newer API's come out you've to take extremely care that no new exceptions causes were added your code doesn't expect. It goes down to the old statement, you can write fortran in any language. the clean coding style while experimenting would be: catch Exception { } Then at later stage before you're releasing a produce you just have to `grep' the whole source code for TODO and fix all occurences. It's actually a question of matter of principle, do we want an language suited for expermints or do we want one for huge stable projects. Take in example a language optimized for expermenting and teaching, people want to get results quickly, without having to write empty templates. Think of the C 'hello world' program, how many lines of it are just workaround you first have to tell you're pupils ignore all that it's framework like , so a teacher want's a language with results when already writing just one line, same goes for the expreminter. However a programmer targeted to stable software actually wants a strong frame, he knows already all the rudimentary surrondings, and wants them. A single line dropped somewhere suddendly doing something for itself is a horror for him. People with different diserers will come and have different and converse expectations in a language, it's matter of the language to target which aspects it wants to cover and which a secondary. Strong or weak exceptions are just such a case. - Axel
Sep 02 2001
This is a choice between D being a language to create large, stable, correct codebases or one for quick hacks. Ultimately that choice is not mine to make, but if D is for hacking, then I'm sticking with C++. I can live with operator overloading, I can bare generics, but ignoring exception specificiation - which is a fantastic tool for creating correct code - is just stupid, especially when it doesn't stop you hacking if you want to. Peter.
Sep 02 2001
[snip!]The theory is that if the compiler forces the programmer to either handle the exception or pass it on in an exception specification, then the programmer's attention will always be brought back to the possibility of errors and they will thus properly take care of them. I think the problem is that this is an untested assumption we're making as language designers that falls into the field of psychology.It is not an untested assumption. It might have been many years ago Java when was introduced (about seven years ago?) but there has been enough testing of the idea since. My practical experience, the experience of people I have worked with and that of others on this newsgroup attests that this idea does work. Peter.
Sep 02 2001
"kaffiene" <kaffiene xtra.co.nz> wrote in message news:9mt8rs$2u2h$2 digitaldaemon.com...[snip!]thatThe theory is that if the compiler forces the programmer to either handle the exception or pass it on in an exception specification, then the programmer's attention will always be brought back to the possibility of errors and they will thus properly take care of them. I think the problem is that this is an untested assumption we're making as language designers that falls into the field of psychology.It is not an untested assumption. It might have been many years ago Java when was introduced (about seven years ago?) but there has been enough testing of the idea since. My practical experience, the experience of people I have worked with and that of others on this newsgroup atteststhis idea does work.My own experience agrees with this. I agree that there is a tendency displayed by lazy programmers to use "throws Exception, Error" to avoid actually thinking about what they are doing. For hacks this is perfectly acceptable and not a tremendous burden to anyone. But when it comes to real, live, actual, customers-screaming-down-the-phone production code it quickly becomes clear to even the sloppiest programmer that all they're doing is *deferring* exception handling, not avoiding it. When I was working with Java, a colleague of mine at the time - a mathematician in programmer's clothing and the second laziest programmer I have ever worked with - was very firmly in the the "throws Exception" camp. Over time he moved towards my way of thinking (handle early) because he found that his style of coding (handle late) requires much hairier handling code further up the call stack if you want your software to be presentable to a paying customer... Or even to a non-paying customer ;-) It the risk of sounding evangelical, I urge anyone who resists the idea of strict exception specification to actually try it. You'll find that your code /feels/ much more robust. This alleviates much stress from the working programmer and is well worth the small amount of extra effort. All of that being said, I would accept Russ' compiler switch compromise - albeit grudgingly. Though I would like to have some way of knowing whether 3rd party D binaries are "compliant". I don't want to ship code that could explode in a customer's face. Or rather, if it is going to explode, I'd like it to be sure that it's *my* fault - that is, in code that I have some control over. Regards, John "ashamed to be an Australian at the moment" Carney.
Sep 02 2001
Long time ago I wrote code that tried to go around error handlings by 'recovery' and all kinds of code to somehow halt along after problems. Usually such code ended up becoming far too complex, resulting in even more unknown states. The best is to let the application bomb as quickly as possible, and force the programmer to fix the problem on the spot. Hence delegating the error handling to another level and even ignoring is in my current view not a practical solution. In embedded systems programming it's far better to have the program crash and then you are indeed forced to fix the problem before shipping it. --Kent
Sep 06 2001
Kent Sandvik wrote in message <9n8n4u$ai5$1 digitaldaemon.com>...Long time ago I wrote code that tried to go around error handlings by 'recovery' and all kinds of code to somehow halt along after problems. Usually such code ended up becoming far too complex, resulting in even more unknown states. The best is to let the application bomb as quickly as possible, and force the programmer to fix the problem on the spot. Hence delegating the error handling to another level and even ignoring is in my current view not a practical solution. In embedded systems programming it's far better to have the program crash and then you are indeed forced to fix the problem before shipping it. --KentI've had a long standing disagreement with some people who think that programs should attempt to recover from their own bugs. My feeling is that if a fault is detected, fail immediatedly. Trying to recover from them is like duct taping over rust.
Sep 06 2001
It's an intriguing and disturbing argument. I think I would say that if the language spec leads to (lots of) the kind of hacks Bruce describes, then I would be against exception specification. But is there another way? Looked at Dan's suggestion of not requiring throws clauses. The problem with that is if you call a library function that does declare its exceptions, there is absolutely no way to declare one in your code (as you cannot guarantee you have caught all they throw). That would, of course, encourage writers of library APIs to declare their exceptions...but you get one idiot, and all of a sudden a lot of user code can't use declarations anymore. The alternative is to use C++ -style catch(...) clauses, which, IMHO, are often worse than not catchnig things at all. My thought is that maybe throws checking should be a compiler switch. Let the default setting of the compiler be to check exceptions and to interpret a lack of a throws clause as an explicit "throws nothing" clause. But allow for a compiler switch that causes lack of a throws clause to mean "could throw anything". Then programmers could use loose throwing for their quick hacks, and tight checking for their important code.
Sep 02 2001
Russ Lewis wrote:My thought is that maybe throws checking should be a compiler switch. Let the default setting of the compiler be to check exceptions and to interpret a lack of a throws clause as an explicit "throws nothing" clause. But allow for a compiler switch that causes lack of a throws clause to mean "could throw anything".Maybe with the "hack switch" on, it would still check things, but they would only be posted as warnings...
Sep 02 2001
Russ Lewis wrote:Looked at Dan's suggestion of not requiring throws clauses. The problem with that is if you call a library function that does declare its exceptions, there is absolutely no way to declare one in your code (as you cannot guarantee you have caught all they throw). That would, of course, encourage writers of library APIs to declare their exceptions...but you get one idiot, and all of a sudden a lot of user code can't use declarations anymore.You can get idiots in any language. If you find a language feature that could fix that, I would truly be impressed. I'll assume you meant to say "...if you call a library function that DOESN'T declare its exceptions..", or else you are misrepresenting my argument. First, this hypothetical API designer is an idiot and the API should be considered flawed. Some programs can afford to be quick and dirty. No public API should. Even if a lack of a throws clause implied no exception thrown, you will still get idiots who will declare they throw the exception base class. The compiler cannot fix that. You could still catch the exception in my example given that D was supposed to have a single base class that all exceptions had to be derived from. (Or am I mistaken?) Where ever you would put "catch(...)" in C++ you would put "catch(exception e)" or whatever the base class is in D. I still say you should hound the API developer, or use a different API by someone a little less idiotic. Dan
Sep 02 2001
Even if a lack of a throws clause implied no exception thrown,you will still get idiots who will declare they throw the exception base class. The compiler cannot fix that.No it can, writing 'throws' in the decleration is not alone making the compiler happy. You must actually throw it somewhere, or call a function in your body that throws this exception, or else you've at least a warning if not an error. So if you declare the exceptoin base class in the throws clause you must also throw it somewhere.I still say you should hound the API developer, or use a different API by someone a little less idiotic.I used to have C++ projects that suddendly crashed by the costumer because some code part threw an exception that was not catched. Whats more important quick hacks or stable projects?
Sep 02 2001
Axel Kittenberger wrote in message <9mv24r$r8k$1 digitaldaemon.com>...I used to have C++ projects that suddendly crashed by the costumer because some code part threw an exception that was not catched. Whats more important quick hacks or stable projects?It's common for C and C++ code to crash because the code failed to test for the error return from a function. Even longtime professional programmers make this error. By having errors signalled by throwing an exception, they cannot be ignored by default. If there is no code to catch the exception, the startup code installs an exception handler to print out the error message for the exception (all exceptions are defined to have an explanatory error message associated with them). For batch programs, this in itself will be adequate for most uses. For non-batch programs, at least you get a reasonable error message and graceful exit when the program fails, instead of the C approach of a random crash.
Sep 02 2001
It's common for C and C++ code to crash because the code failed to test for the error return from a function. Even longtime professional programmers make this error.Okay now how many people do check on the return value for fclose() :o)By having errors signalled by throwing an exception, they cannot be ignored by default. If there is no code to catch the exception, the startup code installs an exception handler to print out the error message for the exception (all exceptions are defined to have an explanatory error message associated with them).Well I used MSVC in the past, an the application just halted with an exit code. Not message, nothing. But mabye I just did something wrong. And actually this is the runtime vs. compiletime approval. Why should a error have to be discovered at runtime if it could be tracked at compiletime already? Like uncatched excpetions. And honestly through all economic non high-security software projects we must admit that there are really some code parts that go out untested, like some cases to reaction of certain malfunctions. No 'normal' software project can effort to go through a profiler supported branch decision test analyses high security software goes through. Just take a worst case exception, "NuclearCoreMeltdownException", okay one code piece forgot to catch it and to start emergency shutdown sequence. The compiler doesn't complain because some guys want to do quick hacks without having to write syntatic catch-sugar. Now the application terminates with a nice NuclearCoreMeltdownException raised in code module XYZ line 245 is uncatched, application terminated with exit code -1. But now who starts the emergency sequence? I know this example is very hyperbolical, since software used in this fields is tested through other means as we're used to. But I think you can image what I think about, take in example fclose(), no body with local filesystems thinks about closing a file could fail, but with network filesystems it can, and a really good program should at least inform the user that his file is not saved, and possibly lost. Okay fclose is a bad example as 99% of people ignore it's return value, myself included :( But I think you can imagine what I ment with comiletime vs. runtime security. - Axel
Sep 03 2001
Axel Kittenberger wrote:I believe I've mention in one of the other "exceptions" threads that I was anal. This is what I mean. I will admit, I don't check it every time, I do check it often, even in perl. Go ahead. Laugh!It's common for C and C++ code to crash because the code failed to test for the error return from a function. Even longtime professional programmers make this error.Okay now how many people do check on the return value for fclose() :o)Probably not. I've had the same thing in UNIX. I think my C++ implementation just called abort on uncaught exceptions. Java dumps huge stack traces that fall somewhere between rude and terrifying to the unwashed masses. It sounds like D is going to require behavior of the runtime that is likely to be a little less anti-social.By having errors signalled by throwing an exception, they cannot be ignored by default. If there is no code to catch the exception, the startup code installs an exception handler to print out the error message for the exception (all exceptions are defined to have an explanatory error message associated with them).Well I used MSVC in the past, an the application just halted with an exit code. Not message, nothing. But mabye I just did something wrong.And actually this is the runtime vs. compiletime approval. Why should a error have to be discovered at runtime if it could be tracked at compiletime already? Like uncatched excpetions.The issue is that uncaught exceptions are not necessarily an error. It sounds like D will allow the exception to be the means to pass on an error message and die which is reasonable behavior in a large number of cases. (If only you could give it the exit status too. hint hint)And honestly through all economic non high-security software projects we must admit that there are really some code parts that go out untested, like some cases to reaction of certain malfunctions. No 'normal' software project can effort to go through a profiler supported branch decision test analyses high security software goes through. Just take a worst case exception, "NuclearCoreMeltdownException", okay one code piece forgot to catch it and to start emergency shutdown sequence. The compiler doesn't complain because some guys want to do quick hacks without having to write syntatic catch-sugar. Now the application terminates with a nice NuclearCoreMeltdownException raised in code module XYZ line 245 is uncatched, application terminated with exit code -1. But now who starts the emergency sequence?OK. So this isn't one of those cases where returning a message and exit status would be sufficient.I know this example is very hyperbolical, since software used in this fields is tested through other means as we're used to.True, but I like the idea of a nuclear meltdown being handled automatically by an exception. It just sounds so routine.But I think you can image what I think about, take in example fclose(), no body with local filesystems thinks about closing a file could fail, but with network filesystems it can, and a really good program should at least inform the user that his file is not saved, and possibly lost. Okay fclose is a bad example as 99% of people ignore it's return value, myself included :( But I think you can imagine what I ment with comiletime vs. runtime security.Yes, there should be a way to find out at compiler time if there are any uncaught exceptions. There are project that would definitely use that. But there a lot of genuinely useful programming tasks for with overly strict exception rules would be a burden that bares no benefits. Not everyone is building a Sherman tank. (Or a Nuke Plant for that matter.) There must be room for tradeoffs. Dan PS: I still like the idea of a nuclear meltdown being handled by a mere exception. I can't imagine what it would be like to write the code that monitor the situation and just determine "hmm... The core is melting. I guess I'll throw an exception. My work is done." :-)
Sep 03 2001
Okay now how many people do check on the return value for fclose()I believe I've mention in one of the other "exceptions" threads that I was anal. This is what I mean. I will admit, I don't check it every Go ahead. Laugh!Absolutly not, Most times I either forget about it, or are to lazy, or don't know what it should do else. Well small stack traces are nice to have either way. For costumer support, if somebody calls you with the messge "your application just segfaulted", no matter what else he babbles, having a stack trace gives you a very defined idea where to problem arised. Especially on GUI application it's a nasty event if the application just vanishes from the user, at least a message box and some explanation what happened should appear. Okay windows learned this and now even KDE has nice crash handles, and if you've a debug build of KDE it does print out a nice stack trace, you can copy/paste for bug reports. But okay I think it's task of the application to handle segfault signals, and to investigate it's own status on this signal.Not everyone is building a Sherman tank. (Or a Nuke Plant for that matter.) There must be room for tradeoffs.Yes I said it's overstated. On PC's it are more trivial things like FileIoException - write access not allowed. Something you can miss when coding an application, not thinking about your application could be runned in places where you don't have write access to your direction. Or the target system is malfunctioning because the current user doesn't even have access to /tmp, or somebody deleted the /tmp or whatever.PS: I still like the idea of a nuclear meltdown being handled by a mere exception. I can't imagine what it would be like to write the code that monitor the situation and just determine "hmm... The core is melting. I guess I'll throw an exception. My work is done." :-)Okay, okay it was a bad example, as normally there is even an own circuit respsonsible just for this. But staying in practical/physical world you've quite often conditions an producure says: man, under this situation I can never continue my task, and it -must- be handled proparly by a single instance. Just imagine every possible code loop would have to handle itself criticial errors, diffrerent programmers result in different solutions. So the answer to how does this system react on this or this situation? would have to be answered, well that depends on which state the software currently is. Hmmm okay from my phantasy I've imagine a new hopefully better example. Take the airplane autopilot, in case of an engine starting to catch fire, the autopilot will no longer care to reach the target city or to fly in for maximum comfortability for the passanger. It raises an 'EngineCatchedFireException' :o) and code pops back until a main loop, which catches it, and handles the exception by giving control to a complete other code part, since flying with just one wing is very different than with two :o) (but from what I heared it's still possible). Again if the application exits with a callback stack.... okay enough phantasy :o) - Axel
Sep 03 2001
Axel Kittenberger wrote:Sorry. For some reason the whole scenario about the nuke plant came to me as a twisted Monty Python skit. It was a valid example of a critical application, exaggerated but that just helps to punctuate the idea. I just got this weird idea about it into my head and it gave me a good chuckle. I'm just warped. DanPS: I still like the idea of a nuclear meltdown being handled by a mere exception. I can't imagine what it would be like to write the code that monitor the situation and just determine "hmm... The core is melting. I guess I'll throw an exception. My work is done." :-)Okay, okay it was a bad example, as normally there is even an own circuit respsonsible just for this. But staying in practical/physical world you've quite often conditions an producure says: man, under this situation I can never continue my task, and it -must- be handled proparly by a single instance. Just imagine every possible code loop would have to handle itself criticial errors, diffrerent programmers result in different solutions. So the answer to how does this system react on this or this situation? would have to be answered, well that depends on which state the software currently is. Hmmm okay from my phantasy I've imagine a new hopefully better example. Take the airplane autopilot, in case of an engine starting to catch fire, the autopilot will no longer care to reach the target city or to fly in for maximum comfortability for the passanger. It raises an 'EngineCatchedFireException' :o) and code pops back until a main loop, which catches it, and handles the exception by giving control to a complete other code part, since flying with just one wing is very different than with two :o) (but from what I heared it's still possible). Again if the application exits with a callback stack.... okay enough phantasy :o)
Sep 04 2001
Axel Kittenberger wrote:Even if a lack of a throws clause implied no exception thrown,This is were we differ then. I do believe a function should be able to claim it throws an exception that it in fact does not. This is why I replied to my first message on this thread. The basic reason is that a standard API may allow for a given type of exception, when not all implementation of that standard will throw that exception. Either the API user has to use version statements in his throws clause (if that is even possible) or he will not be able to code to the standard and still use the more robust implementations of that standard. Requiring a function to actually throw every exception in it throws clause will be the source of many problems even for the most anal of developers. An unused exception is not like an unused variable in a function. Requiring a function to throw every exception in it throws clause is more like requiring a function with a return type of int to return every value from int.min() to int.max() at some point in its code.you will still get idiots who will declare they throw the exception base class. The compiler cannot fix that.No it can, writing 'throws' in the decleration is not alone making the compiler happy. You must actually throw it somewhere, or call a function in your body that throws this exception, or else you've at least a warning if not an error. So if you declare the exceptoin base class in the throws clause you must also throw it somewhere.My experience tells me both. My proposal would in fact satisfy the requirements of both. It would require allowing exceptions in the throws clause that aren't in fact thrown, it would require that a function be allowed to throw an exception if it is not in the throws clause as long as it is derived from one of the types in the throws clause. This already assumes that there is a shared base class for all exceptions. The spec calls it Error. class e1 : Error {} // Error is the exception base class class e2 : e1 {} class e3 : e1 {} // I can throw nothing void f() throws(); // I could throw anything including, but not limited to e1, e2 & e3 void g() throws(Error); // I could throw anything including, but not limited to e1, e2 & e3 void h(); // I could throw any subclass of e1 including, but not limited to e2 & e3 // I cannot throw Error or anything else not derived from e1 void i() throws(e1); // I could throw any subclass of e2 including, but not limited to e3 // I cannot throw e1 or Error or anything else not derived from e2 void j() throws(e2); // I could throw any subclass of e2 or e3 // I cannot throw e1 or Error or anything else not derived from e2 or e3 void k() throws(e2, e3); try{ f(); g(); h(); i(); j(); k(); }catch(Error){ // ALL exceptions WILL be caught here, // without exception :-) } All of the exceptions thrown by these functions could be caught by a 'catch(Error)' because all exceptions MUST be derived from Error or one of its descendants. Nothing can slip through. It is bullet proof and air tight. No exceptions. The lazy can be lazy. The non lazy can be non lazy, even when using code written by a lazy developer. The non lazy would probably have an easier time if he used code exclusively from other non lazy programmers. Even then he has to deal with the idiots and he has the tools he needs to do so. DanI still say you should hound the API developer, or use a different API by someone a little less idiotic.I used to have C++ projects that suddendly crashed by the costumer because some code part threw an exception that was not catched. Whats more important quick hacks or stable projects?
Sep 02 2001
This is were we differ then. I do believe a function should be able to claim it throws an exception that it in fact does not. This is why I replied to my first message on this thread. The basic reason is that a standard API may allow for a given type of exception, when not all implementation of that standard will throw that exception. Either the API user has to use version statements in his throws clause (if that is even possible) or he will not be able to code to the standard and still use the more robust implementations of that standard. Requiring a function to actually throw every exception in it throws clause will be the source of many problems even for the most anal of developers. An unused exception is not like an unused variable in a function. Requiring a function to throw every exception in it throws clause is more like requiring a function with a return type of int to return every value from int.min() to int.max() at some point in its code.True, I thought futher over that, in the matter of polymorphism requiring to throw all throws declared things is a horror.My experience tells me both. My proposal would in fact satisfy the requirements of both. It would require allowing exceptions in the throws clause that aren't in fact thrown, it would require that a function be allowed to throw an exception if it is not in the throws clause as long as it is derived from one of the types in the throws clause.I don't think this will benefit in the matter of readability. Why should one want to throw a child of the throws clause? Catching through inheritence by parents, okay. But throwing childs? This already assumes that there is a shared base class for allThe lazy can be lazy. The non lazy can be non lazy, even when using code written by a lazy developer.Thats another main objective we might differ. Does the language encorage projects written by a single author, or for multiple authors. This statment goes against projects where more than one code is envolved, and this is exactly the place most modern language approach at. Look who uses C++ succesfull in practice, most of these who do it but an additial coding rules upen C++ and force themself to a defined subset of the language, project teams where every member is allowed to use all features of C++ like he finds them are usually not so successfull, because C++ is bloated of features. Now I darkly remember what was the mission statment of D? " Programming managers who are forced to rely on C programming style guidelines to avoid common C bugs." So this goes against the lazy and non lazy approach :o) - Axel
Sep 03 2001
Axel Kittenberger wrote:This is a concession to the fact that some venders will implement things in a way that will allow they to return more granular error information than standard designers had anticipated or felt they could expect from all vendors. If a standard API stated that a given method X() could throw NetworkException in the case of network problems, a given vendor could subclass that exception to provide different forms of network exceptions to differentiate between cases that their platform can correct and those that can't be helped. This could allow people who are willing to tie themselves to the platform increased granularity of error detection and possibly allow them to react better to certain exceptional situations. Developers who code to the standard would not be affected by this increased granularity. Developers who do use the extra exceptions would have to find out about them somewhere other than the throws clause, which is sub optimal for them. I guess there would be other ways around this one too, but it feels most natural to me. I was just assuming that the exceptions in the throws clause might make their way into a function signature somehow, and I would not want someone who writes to a standard to get bitten because some one else was an over achiever in error detection.My experience tells me both. My proposal would in fact satisfy the requirements of both. It would require allowing exceptions in the throws clause that aren't in fact thrown, it would require that a function be allowed to throw an exception if it is not in the throws clause as long as it is derived from one of the types in the throws clause.I don't think this will benefit in the matter of readability. Why should one want to throw a child of the throws clause? Catching through inheritence by parents, okay. But throwing childs? This already assumes that there is a shared base class for allThis is the biggest difference I guess. It is good to plan things so good practices can be handled and enforced by the language. Large projects will benefit from it. On the other hand, most of my experience has shown me that the quick fix tools and simple utilities are just as important as huge billion line programs. I would also guess that a number of scientists writing simulations would not be as interested in these strict features. They would want to be aware of errors, but they would be just as happy to let the simulation die, so they can correct the error. It's the difference between shipping a product and doing in house, batch style work. Not every task requires rock solid stability and it is not practical to impose such constrains on everyone. It is necessary that to provide the tools that will allow people to easily get stability if they want it, but there needs to be room for the tradeoffs that have to happen in the real world. We could say that D is only for "Programming managers who are forced to rely on C programming style guidelines to avoid common C bugs" but I suspect that such a stance would make D just another language that is only used by a few large companies use for a short period of time. I guess the thing I like about have the exception handling that I've been whining about is that you can take a function by a lazy developer, add a throws clause, and the compiler will tell you (through error messages) what exceptions you need to handle or pass on. So it is easy to start working on a chuck of code without paying much attention to error handling, and when you are ready to clamp down, it would be pretty easy. DanThe lazy can be lazy. The non lazy can be non lazy, even when using code written by a lazy developer.Thats another main objective we might differ. Does the language encorage projects written by a single author, or for multiple authors. This statment goes against projects where more than one code is envolved, and this is exactly the place most modern language approach at. Look who uses C++ succesfull in practice, most of these who do it but an additial coding rules upen C++ and force themself to a defined subset of the language, project teams where every member is allowed to use all features of C++ like he finds them are usually not so successfull, because C++ is bloated of features. Now I darkly remember what was the mission statment of D? " Programming managers who are forced to rely on C programming style guidelines to avoid common C bugs." So this goes against the lazy and non lazy approach :o)
Sep 03 2001
This is the biggest difference I guess. It is good to plan things so good practices can be handled and enforced by the language. Large projects will benefit from it. On the other hand, most of my experience has shown me that the quick fix tools and simple utilities are just as important as huge billion line programs. I would also guess that a number of scientists writing simulations would not be as interested in these strict features.That's the point, and thats a principle decision languages have to do. From what I read from the walters specs I had the impression he targeted his language to be thought for use by million line programs not as a ideal quick hack tool. For quick hacks a lot of scrip languages are already pretty ideal, or? - Axel
Sep 03 2001
Axel Kittenberger wrote:True. I was just going off some of his comments I've seen on this group. I'm guessing he's after as much middle ground in this area as possible without making a complete sacrifice in error handling. Even with the compromise, D would be worlds better than C. I'm still of the opinion that it would be no worse than java functionally speaking. In any case, I've gone on longer about this than I ever intended to. DanThis is the biggest difference I guess. It is good to plan things so good practices can be handled and enforced by the language. Large projects will benefit from it. On the other hand, most of my experience has shown me that the quick fix tools and simple utilities are just as important as huge billion line programs. I would also guess that a number of scientists writing simulations would not be as interested in these strict features.That's the point, and thats a principle decision languages have to do. From what I read from the walters specs I had the impression he targeted his language to be thought for use by million line programs not as a ideal quick hack tool. For quick hacks a lot of scrip languages are already pretty ideal, or? - Axel
Sep 03 2001
I've gone on longer about this than I ever intended to.Sorry if I was importunate/stolid :/ - Axel
Sep 03 2001
I think your suggestion and reasoning is pretty good. -Walter Dan Hursh wrote in message <3B9326BB.44475274 infonet.isl.net>...Axel Kittenberger wrote:baseEven if a lack of a throws clause implied no exception thrown,you will still get idiots who will declare they throw the exceptioninclass. The compiler cannot fix that.No it can, writing 'throws' in the decleration is not alone making the compiler happy. You must actually throw it somewhere, or call a functionifyour body that throws this exception, or else you've at least a warningbynot an error. So if you declare the exceptoin base class in the throws clause you must also throw it somewhere.This is were we differ then. I do believe a function should be able to claim it throws an exception that it in fact does not. This is why I replied to my first message on this thread. The basic reason is that a standard API may allow for a given type of exception, when not all implementation of that standard will throw that exception. Either the API user has to use version statements in his throws clause (if that is even possible) or he will not be able to code to the standard and still use the more robust implementations of that standard. Requiring a function to actually throw every exception in it throws clause will be the source of many problems even for the most anal of developers. An unused exception is not like an unused variable in a function. Requiring a function to throw every exception in it throws clause is more like requiring a function with a return type of int to return every value from int.min() to int.max() at some point in its code.I still say you should hound the API developer, or use a different APIbecausesomeone a little less idiotic.I used to have C++ projects that suddendly crashed by the costumersome code part threw an exception that was not catched. Whats more important quick hacks or stable projects?My experience tells me both. My proposal would in fact satisfy the requirements of both. It would require allowing exceptions in the throws clause that aren't in fact thrown, it would require that a function be allowed to throw an exception if it is not in the throws clause as long as it is derived from one of the types in the throws clause. This already assumes that there is a shared base class for all exceptions. The spec calls it Error. class e1 : Error {} // Error is the exception base class class e2 : e1 {} class e3 : e1 {} // I can throw nothing void f() throws(); // I could throw anything including, but not limited to e1, e2 & e3 void g() throws(Error); // I could throw anything including, but not limited to e1, e2 & e3 void h(); // I could throw any subclass of e1 including, but not limited to e2 & e3 // I cannot throw Error or anything else not derived from e1 void i() throws(e1); // I could throw any subclass of e2 including, but not limited to e3 // I cannot throw e1 or Error or anything else not derived from e2 void j() throws(e2); // I could throw any subclass of e2 or e3 // I cannot throw e1 or Error or anything else not derived from e2 or e3 void k() throws(e2, e3); try{ f(); g(); h(); i(); j(); k(); }catch(Error){ // ALL exceptions WILL be caught here, // without exception :-) } All of the exceptions thrown by these functions could be caught by a 'catch(Error)' because all exceptions MUST be derived from Error or one of its descendants. Nothing can slip through. It is bullet proof and air tight. No exceptions. The lazy can be lazy. The non lazy can be non lazy, even when using code written by a lazy developer. The non lazy would probably have an easier time if he used code exclusively from other non lazy programmers. Even then he has to deal with the idiots and he has the tools he needs to do so. Dan
Sep 03 2001
Dan Hursh wrote:You can get idiots in any language."If you invent an idiot-proof computer...they will invent a better idiot!"If you find a language feature that could fix that, I would truly be impressed. I'll assume you meant to say "...if you call a library function that DOESN'T declare its exceptions..", or else you are misrepresenting my argument. First, this hypothetical API designer is an idiot and the API should be considered flawed. Some programs can afford to be quick and dirty. No public API should.Absolutely. I didn't mean to imply that having non-strict throws clauses would *cause* bad library APIs. What I was intending to say was that programmers are fundamentally lazy, and that the use of the language will tend to gravitate towards the quickest & dirtiest way. If the default setting of the language is to have strict exceptions, I would guess that more programs (and a higher percentage of library APIs) will use it so as to "not have to bother with the compiler switches." Ofc, you will always have idiots and anal people on both ends in any language. Having this be the default puts additional pressure on designers of library APIs to write "good" APIs. If they want their API to be interoperable with my program, and the default of my compiler is to require strict exceptions, they are more likely to declare those strict exceptions "just to make it work."
Sep 04 2001