> A reasonable attitude for client-side code, perhaps, ('oh it blew up, I'll reopen the app and try again/rerun the script'), but I think not so reasonable for server-side code..
This seems like a response to something that wasn't my comment. I even went out of my way to state what I thought might be obvious: "pay as much attention as required to make things work".
Handling errors is a given in this thread. The question was how to represent that in the structure of the program.
> There's element of personal preference here.
I agree that there's some of that, but if you accept that the main purpose of programming language syntax is to ease reading, writing, and understanding programs, then preference only matters to the extent you can know it, and most of us can assume that we do not know the preferences of the people reading and trying to understand our code. Given that, we must try to use somewhat more objective measures.
When reading code, is it more useful to get a broad overview of the algorithm, or more useful to dive into every possible branch? The answer to this won't always be the same, but for a given type of code it will likely lean heavily toward either breadth-first or toward depth-first readings, which correspond fairly closely to whether error handling is done locally at the site of the error. Further, I think most programs will benefit more from a breadth-first organization, such that errors are better handled (syntactically) in a way that doesn't interrupt the process of understanding what the code is supposed to do.
Go has a lot of things I like, but the difficulty of laying out a clear "do this, then this, then this, then that" is not one. Either you end up with "do this (or handle the error from trying to do that by doing this other thing), then this (unless there's an error here, in which case...)", or you abuse panic, or explicitly ignore errors. If you're in this situation, then the first is the best of a bad lot, but unless you're doing some very finicky, low-level code, it would be nicer to be able to handle errors outside of the purposeful flow of the application.
I agree that having a distinction between different kinds of errors is nice, but errors of type (1) are not the purpose of your code. They're problems that prevent your code from fulfilling its purpose. That's a whole different conversation, though. :/
> errors of type (1) are not the purpose of your code. They're problems that prevent your code from fulfilling its purpose.
I don't really agree with that. In a module that checks whether a user has the right credentials to perform a given task, for instance by checking the used IP is correct and a correct password is given within 3 attempts (or else the account is blocked), dealing with errors (checking password is valid, checking IP is valid, checking account is not blocked, blocking it if needed) is the purpose of the module.
This is the same with any kind of automaton. Knowing when you go into an error state and how you get out of it is part of the problem you deal with.
Well, ultimately all I can say is that my personal experience is it's easier for me to build software to the level of quality I want using an explicit error handling regime (like Go) than an implicit, exception-throwing regime (which I've used with Python and C++). YMMV.
This seems like a response to something that wasn't my comment. I even went out of my way to state what I thought might be obvious: "pay as much attention as required to make things work".
Handling errors is a given in this thread. The question was how to represent that in the structure of the program.
> There's element of personal preference here.
I agree that there's some of that, but if you accept that the main purpose of programming language syntax is to ease reading, writing, and understanding programs, then preference only matters to the extent you can know it, and most of us can assume that we do not know the preferences of the people reading and trying to understand our code. Given that, we must try to use somewhat more objective measures.
When reading code, is it more useful to get a broad overview of the algorithm, or more useful to dive into every possible branch? The answer to this won't always be the same, but for a given type of code it will likely lean heavily toward either breadth-first or toward depth-first readings, which correspond fairly closely to whether error handling is done locally at the site of the error. Further, I think most programs will benefit more from a breadth-first organization, such that errors are better handled (syntactically) in a way that doesn't interrupt the process of understanding what the code is supposed to do.
Go has a lot of things I like, but the difficulty of laying out a clear "do this, then this, then this, then that" is not one. Either you end up with "do this (or handle the error from trying to do that by doing this other thing), then this (unless there's an error here, in which case...)", or you abuse panic, or explicitly ignore errors. If you're in this situation, then the first is the best of a bad lot, but unless you're doing some very finicky, low-level code, it would be nicer to be able to handle errors outside of the purposeful flow of the application.
I agree that having a distinction between different kinds of errors is nice, but errors of type (1) are not the purpose of your code. They're problems that prevent your code from fulfilling its purpose. That's a whole different conversation, though. :/