3 ms·
If you return an `Either[Error, T]` (to use Scala syntax) then in case of error you never have to construct a T and the caller can never read one by accident on
by red_admiral 4y ago
If you return an `Either[Error, T]` (to use Scala syntax) then in case of error you never have to construct a T and the caller can never read one by accident on the error path, whereas if you return a pair (T, error) then you can hit at least three cases:
1. T is an int that's sometimes legitimately zero, if you return (0, err) and the caller isn't careful they can look at the 0 without realising it's not valid.
2. T is a 'pointer' type so you return (null, error) and the caller tries to dereference the pointer anyway (one example I've seen is inserting a logging statement for debugging purposes just _before_ the error-check, along the style of `logger.debug("foo {t.name}")` where the braces interpolate stuff).
3. T lives in a strongly typed world where there's no convenient null value available (maybe your language distiniguishes between "definitely a T" and "either a T or null") so you somehow have to construct an instance of a T even though you're never going to use it and it'll most likely be invalid in some sense.
That doesn't mean the golang approach is bad - especially not in golang itself - but you do need to know how to use it correctly. Then again, using monadic error handling in golang would probably be strictly inferior - it's not that you can't define one, but the language doesn't have the syntactic sugar to handle it like e.g. Scala does, and I find that being able to use that sugar to get some readability for the approach is the whole point of monadic error handling.