2 ms·
> That’s a lot of repetitive [error handling] work. But we can make it easier on ourselves by introducing a small wrapper type, errWriter. > errWriter fulfils
by shoo 8y ago
> That’s a lot of repetitive [error handling] work. But we can make it easier on ourselves by introducing a small wrapper type, errWriter.
> errWriter fulfils the io.Writer contract so it can be used to wrap an existing io.Writer. errWriter passes writes through to its underlying writer until an error is detected. From that point on, it discards any writes and returns the previous error.
this is a cute trick.
In some cases it might produce a great result. For example, floating point nan values work roughly like this: a special error values included in the type that can be computed upon without needing to write special control flow until you explicitly need to check the final computed result to see if you got an actual value or the nan value.
but I fear the applicability of this trick in go is limited as it relies on a heap of idiosyncracies belonging to this example:
The chain of potentially error-ing operations that are being performed all involve a value of the same type that can be wrapped. In a less contrived example there would be a variety of different types involved in the sequence of possibly error-ing operations.
The code that is processing the wrapped error-hiding type roughly must not perform side effects when processing an apparently non-erroring computation, since now the error wrapper type is stopping the code from aborting early. It's completely non obvious that this transformation will be correct (ie result in a program with equivalent behaviour to the original program) without reading exactly through the implementation of everything that touches the error wrapper. This isn't helped by go not having a way to tag functions as pure.
The new code now superficially looks like it is wrong as it isn't bothering to check error values of the functions it is calling in the usual way. This will probably cause a spray of linter warnings about failing to handle possible errors in your CI build.
In other languages a much more general way to address this kind of problem could be:
error monads ; or
exception handling
Which can be used to short circuit the entire normal control flow.
- masklinn 8y ago> In other languages a much more general way to address this kind of problem could be: error monads ; or exception handling errWriter is quite literally "let's do monadic error handling, except not just without monads but without generics or reified errors". And thus it can only handle a single source or error type. Also FWIW monadic error handling != error monads. For instance Rust does the former, but its type system can't express the latter (so there is no monad or functor abstraction on top of Result).