4 ms·
Yup, it's also basically a requirement for "asynchronous" APIs. Or the other way around, returning immediate error codes requires synchronization, and therefore
by jstimpfle 4y ago
Yup, it's also basically a requirement for "asynchronous" APIs. Or the other way around, returning immediate error codes requires synchronization, and therefore increases coupling.
I don't care how many fans there are - when I can reduce error checking clutter by a factor of 5, and do error handling where/when it best fits, I know it was the right approach.
- badpun 4y agoDepends on the language I guess. Asynchronous APIs in Scala for example use way nicer ways of handling errors (they essentially return something like a Future of a type than can be either the return value or hold the details about the error that occured).
- jstimpfle 4y agoWhat can I say, a future is exactly the kind of handle I described, isn't it? The difference being that these async frameworks do too much work in composing all these futures IMO. I prefer simple explicit event handling. Async runtimes probably make sense for web request handlers though.
- badpun 4y agoWith monadic futures, you can elegantly compose them and basically have great error handling while barely writing a line of code. In your solution, I foresee codebase where 50% of the code are ifs which check the state of the context.
- jstimpfle 4y agoWell I described an approach how to structure code to avoid checking object states (error handling) most of the time. For example, when you use a FILE like handle to write to a file stream or similar, you don't have to check each time you call fwrite(). It's the opposite, it's sufficient to check at the very end (if you're interested at all). The way I've been writing code for the last 2 years or so, there is almost no error handling at all. I check buffer ranges whenever I'm writing directly to memory using a pointer + capacity / size pair. I could probably avoid that as well with some C++ magic but even that is rare enough that I don't even bother. Most of the other error checks are in the application setup / teardown code in the hull of the application - typically one check per codebase per error or object type. Nothing to worry about, I would have to do just as much work with RAII or any other mechanism. The easiest way to handle an error, for a statically set up object, is to attach it to the "process object" i.e. exit() immediately. The next easiest way is to attach the error to some subordinate state object, where the appropriate subsystem can later pick the error up and reset the object or take appropriate action. I've already had my phase of wasted months and years composing monads and frankly I don't want to get back there but would rather get real work done. In practice, working with monads amounts to a lot of headaches how to wrap, unwrap, and lift things that I could have simply written as straightline code in a non-fancy language, after spending some reasonable thought when and what things should actually best happen. If you need complicated type hackery to automate writing error handling code, what you are doing is... too complicated.
- badpun 4y agoI dunno, I’m not a huge fan of effect-based FP as well, but have started to see its merits in my current job. I guess it’s like you said, i.e. methods in your library are checking if there was an error already and if there was, don’t do the required processing. With effectful monads, you get that out of the box - it just happens automatically. I think it’d prefer that aproach for a serverside project. For anything low-latency though, it’s obviously too slow (at least in Scala).