Personal computing discussed
Moderators: renee, SecretSquirrel, just brew it!
SecretSquirrel wrote:Here is another way to look at it, that lines up with what the "exceptions are exceptional" folks are getting at. If you are throwing an exception in your code, the expectation should be that the execution thread terminates. The purpose here is to log as much state and information as possible and give a good traceback, as well as to (maybe) try and clean up.
If a library you are calling throws an exception, whatever thing that library handles should be "terminated". For example, if you have a database library that throws an exception, it should be expected that you cannot cleanly close the database connection, commit transactions, etc. At that point, you should assume any attempt to access that database will fail, and/or make things worse. The library is signaling that it has encountered an situation that it cannot handle, either literally, or figurative in that the library designer cannot chose the correct recovery path and leaves it to you the application writer.
--SS
Buub wrote:SecretSquirrel wrote:Here is another way to look at it, that lines up with what the "exceptions are exceptional" folks are getting at. If you are throwing an exception in your code, the expectation should be that the execution thread terminates. The purpose here is to log as much state and information as possible and give a good traceback, as well as to (maybe) try and clean up.
If a library you are calling throws an exception, whatever thing that library handles should be "terminated". For example, if you have a database library that throws an exception, it should be expected that you cannot cleanly close the database connection, commit transactions, etc. At that point, you should assume any attempt to access that database will fail, and/or make things worse. The library is signaling that it has encountered an situation that it cannot handle, either literally, or figurative in that the library designer cannot chose the correct recovery path and leaves it to you the application writer.
--SS
I think this may be overkill. There are certainly paradigms where this may be a workable model. But there are also very valid frameworks where exceptions simply mean something failed or an error occurred, and it can be dealt with cleanly. In fact, the C++ standard deals quite explicitly with the state of objects after things like exceptions. Leaving things in an indeterminate state is actually poor design, IMHO.
ret=functiion(arg1, arg2, arg3);
if(!ret) {
switch(errno) {
case err1:
goto EXIT_ERR1;
break;
case err2:
goto EXIT_ERR2;
break;
case err3:
goto EXIT_ERR3;
break;
default:
goto EXIT_DEFAULT;
break;
}
}
Kiniry also writes that "As any Java programmer knows, the volume of try catch code in a typical Java application is sometimes larger than the comparable code necessary for explicit formal parameter and return value checking in other languages that do not have checked exceptions. In fact, the general consensus among in-the-trenches Java programmers is that dealing with checked exceptions is nearly as unpleasant a task as writing documentation. Thus, many programmers report that they “resent” checked exceptions. This leads to an abundance of checked-but-ignored exceptions".
UberGerbil wrote:My attitude generally is that library routines should always tell you when there's a problem, but should do so in a way that you can ignore (at your peril) without convoluted code. Some language designs encourage that, some discourage it, and I tend to dislike the latter (though that constitutes a tiny part of my overall opinion of a language).
Ryhadar wrote:Microsoft wrote:Remarks
The First<TSource>(IEnumerable<TSource>) method throws an exception if source contains no elements. To instead return a default value when the source sequence is empty, use the FirstOrDefault<TSource> method.
For what it's worth, I almost always use .FirstOrDefault() and almost never .First(). So, if I were using your LinkedList library I'd probably prefer your convention, derFunkenstein.
NovusBogus wrote:For this I'd say search the existing code base for a similar example and do whatever was done there, for consistency. Both approaches have advantages and disadvantages, highly dependent on context.
derFunkenstein wrote:NovusBogus wrote:For this I'd say search the existing code base for a similar example and do whatever was done there, for consistency. Both approaches have advantages and disadvantages, highly dependent on context.
I wrote the C# project's codebase from scratch. What do I do then?
FlamingSpaceJunk wrote:Really, if it's your own code, you should be able to handle any problems, and exceptions should only be thrown when accessing external resources, dealing with external input, or executing potentially dangerous operations (Anything where a lock, semaphore, or mutex should be set, but it isn't going to happen for various reasons).
derFunkenstein wrote:NovusBogus wrote:For this I'd say search the existing code base for a similar example and do whatever was done there, for consistency. Both approaches have advantages and disadvantages, highly dependent on context.
I wrote the C# project's codebase from scratch. What do I do then?
NovusBogus wrote:Java and particularly .NET love exceptions and exception handling, so in those environments I would say that exceptions should be thrown for both unexpected/unusable results and nonsensical input that fails basic validation
NovusBogus wrote:You typically want to fail gracefully at the top levels of the application, and fail explicitly and decisively further down in the function calls and libraries. Otherwise what happens is that each layer of the application starts creatively interpreting the results of its function calls ("We got back -1, but is that the error-code -1 or the integer -1? And if it's an error code, which of the 93 error code enums are we supposed to look it up in? Better check the phases of the moon for guidance!") and everything goes to hell in a handbasket when someone tries to add new functionality to one of those functions in the future. I work with an extreme example of such a code base right now, and it is not pretty. Hilarious, in a Gilbert Gottfried dead baby comedy kind of way, but not pretty.
NovusBogus wrote:Incidentally, if you're not already doing it I suggest that you always separate your UI code and 'core' logic into separate classes and code files. Separating a software application into distinct layers like this is common practice in industry, and one of those things I wish I'd gotten into the habit of when I was still learning basic coding techniques.
if (index >= size || index < 0) {
throw new IndexOutOfBoundsException();
}
derFunkenstein wrote:Well, I did it. I threw an exception.
In the Java midterm tonight, the programming part of the exam was to re-implement a Node class and create a LinkedList class that at least adds first, adds last, and adds at index i. That last one can throw an exception.Code: Select allif (index >= size || index < 0) {
throw new IndexOutOfBoundsException();
}
My lab partner would shed a tear of pride.
derFunkenstein wrote:You're right. It would make more sense to send two nodes to that method with one of them being a reference to either the "after". But he wanted us to pass in a number and insert at that position, which is weird.
Waco wrote:I don't like delving into the actual order of many operations - but when determining the right algorithm to use it's often quite helpful to plug in expected average bounds, upper limit bounds, and "the guy using this is using it in crazy ways" bounds to determine how many iterations it takes to do that operation. It's not exact but it's extremely easy and it can quickly highlight poor choices in data structures and search methods.
Waco wrote:Talk about coincidence. I ended up rewriting a queue insert today because someone decided that a linked list of a few million items could be used the dumb way...iterating the whole damn thing to insert at the end.
It's amazing how changing 5 lines and adding an extra pointer can save a few million iterations and memory accesses...
derFunkenstein wrote:Waco wrote:Talk about coincidence. I ended up rewriting a queue insert today because someone decided that a linked list of a few million items could be used the dumb way...iterating the whole damn thing to insert at the end.
It's amazing how changing 5 lines and adding an extra pointer can save a few million iterations and memory accesses...
Wait...to add to the *end* of the queue? Wouldn't they just keep track of the tail and use that?
I suppose that's what you did...
just brew it! wrote:Yeah, I rarely bother with a detailed analysis of what order an algorithm is; if you can just eyeball it and make an educated guess as to whether it is better than, equivalent to, or worse than linear, that's generally good enough.
derFunkenstein wrote:Wait...to add to the *end* of the queue? Wouldn't they just keep track of the tail and use that?
I suppose that's what you did...