3 ms·
There are some nice arguments for not overengineering in the comments here, as well as some for there still being merit in explicitly saying what could (typical
by KronisLV 4y ago
There are some nice arguments for not overengineering in the comments here, as well as some for there still being merit in explicitly saying what could (typically) go wrong in the execution of a program. We've already seem the extreme of "never create your custom exceptions", or even something to the tune of "exception handling is a maintenance burden", but I can't help but to wonder about going in the exact opposite direction - even further than the article suggests.
What if we had a language that only had checked exceptions and forced you to deal with anything that can go wrong. Launching a program? You better have some code to deal with an out of memory exception, or some code for dealing with a stack overflow exception. Working with some maths? Well, you better define what should happen in the case of number underflows or overflows, as well as division by zero or whatever else can be inferred by what operators you use. Dealing with a network? Well, be prepared to handle dozens of types of network failures, the brittleness of networks being laid bare to you. Want to deal with reflection? Well, there would probably be none, to avoid too much dynamic behavior.
It's rather obvious why we don't really have languages like that, but at the same time - if writing code in a language like that would be "possible", then surely there's a domain or two out there that might benefit not just from enforced 100% test coverage, but also every single possible error being handled, or at least laid bare. If a program should crash upon particular errors, then the developer might say so explicitly, or otherwise provide logic to recover from those, without ever missing any place where things could go wrong.
Contrast this made up language with your typical Java project: you might use the Spring framework and have a method that exposes a RESTful API that returns some JSON to the client. You'd be amazed at just how many different issues you can run into with even the simplest implementations, it's like a never ending path of discovering more ways for your programs to go wrong. If you can sometimes benefit from your IDE going "hey, this code might throw a NullPointerException", then how much additional assistance you'd benefit from (and how much error handling should be encouraged/enforced) is probably up for debate!
- lmm 4y ago> What if we had a language that only had checked exceptions and forced you to deal with anything that can go wrong. Launching a program? You better have some code to deal with an out of memory exception, or some code for dealing with a stack overflow exception. Working with some maths? Well, you better define what should happen in the case of number underflows or overflows, as well as division by zero or whatever else can be inferred by what operators you use. Dealing with a network? Well, be prepared to handle dozens of types of network failures, the brittleness of networks being laid bare to you. Want to deal with reflection? Well, there would probably be none, to avoid too much dynamic behavior. > It's rather obvious why we don't really have languages like that, but at the same time - if writing code in a language like that would be "possible", then surely there's a domain or two out there that might benefit not just from enforced 100% test coverage, but also every single possible error being handled, or at least laid bare. If a program should crash upon particular errors, then the developer might say so explicitly, or otherwise provide logic to recover from those, without ever missing any place where things could go wrong. A lot of functional languages go in that direction. E.g. if you stick to the non-IO fragment of Haskell then it mostly works like that - things that can error return Either that you have to handle explicitly, and while there's sugar to let you work with that in a similar way to exceptions it will never be entirely hidden. (Within IO you can have exceptions, of course; making a proper algebraic model of how e.g. network I/O works is pretty daunting). Idris or especially Noether go even further in that direction.