4 ms·
"So you can actually just write code like this: do val1 <- someValue val2 <- someFunction val1 val3 <- someFunction val2 someFunction v
by rogpeppe1 14y ago
"So you can actually just write code like this:
do val1 <- someValue
val2 <- someFunction val1
val3 <- someFunction val2
someFunction val3
then, if any of the values return an error, it gets propagated to the end of the code."
I have seen this (the error monad) mentioned before as a "nice" way of handling errors, even with explicit error returns. I beg to differ - the error messages produced by such a program will be obscure, as all the context is lost - if the first call to someFunction fails, for example, there's not necessarily any indication that the error came from that call rather than the one after it.
Go's explicit error handling means that it's easy to add meaningful context wherever relevant - the error messages printed by such a program are likely to be considerably more useful.
In the end, adding error checks is doing useful work. Each error case should be considered individually, and I've often found it to be the case that it's useful to treat errors as regular values (for example by collecting a bunch of errors, or returning the most important error only).
I can understand the control flow of a Go function by inspecting it on the page (without a glance at the documentation). That's a huge plus.
- ufo 14y agoIn theory the lack of context problem only happens if you use Maybe's Nothing to signal errors. Something else such as Either should allow you to include extra data on the error case. As for the error collecting bit I think Haskell can do that as well. Errors are just regular values in Haskell and its just a matter of not using do notation or using a diferent error monad if you want to create a list of errors instead of getting out when the first one occurs. Ill have to agree with you on the control-flow at a glance issue though. This gets really tricky in Haskell, especially when you take lazy evaluation into account.
- papsosouid 14y ago>I beg to differ - the error messages produced by such a program will be obscure, as all the context is lost - if the first call to someFunction fails, for example, there's not necessarily any indication that the error came from that call rather than the one after it. This is completely incorrect. If you use Maybe, then you get Just value or Nothing, in which case there is no indication of what error occurred. This is used when you don't want to consider what error occurred, simply that the computation failed. If you use Either, then you get an error or a value. The error obviously gives the context you are looking for.