func magic() (int, error) {
a, err := foo()
if err != nil {
return 0, err
}
b, err := bar()
if err != nil {
return 0, err
}
c, err := baz()
if err != nil {
return 0, err
}
return a + b + c, nil
}
is less readable, more pedantic, and just generally more soul crushing than: func magic() int throws SomeException {
return foo() + bar() + baz()
}
The explicit error check after every call actually doesn't provide anything useful. If any of foo(), bar(), or baz() fail, magic() is screwed, so why bother writing the same code three times? This shows that the proper place for the error handling isn't in magic(), it's in whoever is calling magic(), and yet, here' I am writing the same do nothing again, again and again in this function, and in all honesty, every function.It's the multivalue return semantics that's the problem here. It's impossible to chain multivalue functions together to write anything succinctly. Worse yet, it's easy to simply ignore the error and create latent bugs because the first return value (which you're probably not ignoring) now has a "zero-value" which can be semantically valid. Whereas if I simply didn't catch the exception, it will be caught, perhaps by main(), but it will be caught, and I won't be populating my data structures with gibberish, which I can very easily do with Go.