Writing that if-construct after every function call doesn't sound like a lot of fun. In fact it sounds like work!
Honestly, I think I'll wait until Go has matured a bit, before I try it for a side-project.
Writing that if-construct after every function call doesn't sound like a lot of fun. In fact it sounds like work!
Honestly, I think I'll wait until Go has matured a bit, before I try it for a side-project.
Furthermore, because Go does unify these conditions, I've found it effective for handling a whole array of differing edge cases that I might have otherwise overlooked. In that regard I've anecdotally found it more effective than most of the habits you see in other languages (I can't say all languages because I haven't used every language out there, but I have developed in excess of a dozen different programming languages over the last 30 years).
In short, in Go error handling becomes a first class citizen rather than a byproduct you begrudgingly need to check for.
Also while it might not be to everyone's tastes, adding "if err != nil {" really does add practically nothing to your overall dev time in real terms.
But I'm not here to advocate one method of error handling over another, nor to try and convince anyone to use Go who might not have otherwise. Obviously you can see I get a little frustrated when people judge it purely on face value but that's because I have spent some time with the language and found it to be surprisingly effective at delivering a stable product.
But how do you compose functions then. You can't write:
f(g(h(...)))
> when people judge it purely on face valueYes, I can see that is frustrating. But I already know the style of programming that requires if-statements instead of exceptions, as I have been programming in C a lot, and I don't want to go back to that style because I'm lazy and I'm sure I will forget to handle some errors. I want my language to deal with this. Honestly, is that really too much to ask? Even javascript has exceptions.
I really think you should try Go before being so convinced about your assertions.
It's not easy to forget error handling in Go.
And letting exceptions bubble up all the way will improve things how?
It's very easy to do so if the function has no useful return value or you don't care for it e.g. Writer.Write: https://play.golang.org/p/cPh0PJoz-v
> And letting exceptions bubble up all the way will improve things how?
Errors the developer forgets (or does not want) to handle will trigger a default handler.
This is the problem with exceptions. They make it too easy to be lazy with your error handling.... Most of the time it's just catch and log, because the code itself has no way of knowing what failed and what succeeded. This is how you get your program in a bad state.... Because maybe you uploaded the file but didn't set the metadata in the API, because the connection broke between those steps.
With go's error handling it forces you to think about "what happens if the code fails here". Its always obvious what code had been executed and what has not.
To get that behavior in exception oriented languages, you'd have to wrap every call in try/catch, which ends up just as verbose as go, if not worse.
> […]
> With go's error handling it forces you to think about "what happens if the code fails here".
Did it run 9 functions or just 1? What do you need to roll back? How do you handle the error?
The inner code could have just bubbled an error by hand from a deeper call (or the library could even have used panic/recover internally to do so, the stdlib used to do that). You have no more idea than in the exceptions-based code unless you have the source available right there, which you'd then also have in an exceptions-based language.
> To get that behavior in exception oriented languages, you'd have to wrap every call in try/catch, which ends up just as verbose as go, if not worse.
So your argument in support of Go's error handling is that the very worst case of exceptions-based error handling you can imagine is about as bad as the baseline case of Go's?
Because errors are a returned interface you don't forget to handle them. In fact you have to explicitly tell the language not to handle them by using a _ token on the function call.
However it sounds like your argument is more personal preference regarding coding style (eg it seems you tend to favour Sexpression style of syntax over the C-style of syntax) and that's reasonable enough. I do write a lot of code like that too - albeit not in Go.
Not all functions have to return an error. You can come across something like func(x, y, func() { ... }) Pretty often.
Anyway, I'm not quite sure how is that different from, say, Ruby's begin...rescue.
Ruby lets you write foo(bar(baz())), the rescue block will just coalesce errors in any of the three calls.
And because Go has no generics and its errors are not reified (handled through MRV which is a special language construct) you can't build abstractions like flatmap/then/>>= which would let you compose these functions (or function calls), you have to handroll every instance.
Good to know (though somewhat disgusting), but for error-returning functions I would assume the external ones would take a single argument aka in foo(bar(baz()) I'd expect
func foo(arg W) (result X, err error)
func bar(arg V) (result W, err error)
func baz() (result V, err error)But imagine the consequences of a program that doesn't do this work. If it is doing something important, fingers crossed.
(Keep in mind: unhandled exceptions are like panics. Not good.)
Writing assembly instructions also sounds like work, and it is, but I'm glad my language/compiler does it for me ;)
If it is not mature enough for you now - it will never be. Right now it is already used in many huge IT companies and extremly popular in China. Writing that if-construct after every function is the design, not the lack of it.