6 ms·
I don't think I've ever in 30+ years of programming seen a runtime assertion that wouldn't be improved by doing something else instead. Writing unit tests and c
by joshka 2y ago
I don't think I've ever in 30+ years of programming seen a runtime assertion that wouldn't be improved by doing something else instead. Writing unit tests and choosing designs that codify the constraints in the type system are two things that are obvious.
The cost of a failing assertion is often incurred at some point where it is most expensive. I know this because I've worked for companies that have charged exorbitant prices for my time to diagnose these sorts of failures.
The cost of a unit test is some learning and some time. LLMs are making the time portion drive towards zero.
As a general rule, I'd say avoid littering your code with assertions. It's a crappy engineering practice.
- BiteCode_dev 2y agoIn Python, contract based programming can be only be done properly with asserts: - You can't use the type system for some constraints. - Asserts can be stripped in production so you don't pay the price for them. - There is not other syntax for that. Unfortunatly, because most devs don't know about "-O" and use asserts for things you should use an Exception for, you can't use it: https://www.bitecode.dev/p/the-best-python-feature-you-cannot https://www.bitecode.dev/p/the-best-python-feature-you-canno...
- samiv 2y agoRespectfully I completely disagree and I think you've got it rather backwards since you've had some bad experiences (understandable). Assert and (unit)tests are completely orthogonal and unrelated things in terms of functionality even though both are aimed at improving the software correctness. Failing an assert in production of course sucks and is costly. But what is more costly is letting the bug slip through and cause hard to diagnose bugs, program incorrectness and even (in some cases) silent address space corruption that will then manifest itself in all kinds of weird issues later on during the program run. The whole point of (correct) use of asserts is to help make sure that the program stays within its own well defined logic and doesn't veer off course and if it does then make that bug immediately as loud as clear as possible. When the bugs are quick to detect and diagnose you'll learn that you have less and less asserts triggering in production and thus you end up with improved product quality. As a general rule I'd say use asserts liberally to verify things such as invariants, post- and pre-conditions and ALWAYS have them built-in. Finally I want to point out that using assert is not ERROR checking (file not found, IP address not resolved, TCP connection failed, system resource failed to allocate, etc.) but BUG checking. Do not write code for BUGS.
- sfink 2y ago> Finally I want to point out that using assert is not ERROR checking (file not found, IP address not resolved, TCP connection failed, system resource failed to allocate, etc.) but BUG checking. > Do not write code for BUGS. I have nothing to add, but am quoting the above because it is very well put.
- joshka 2y ago> since you've had some bad experiences No, I've had great experiences with assertions in code. People have paid my salary because the assertions are invalid and cause more problems than they solved. :D > Failing an assert in production of course sucks and is costly. But what is more costly is letting the bug slip through and cause hard to diagnose bugs, program incorrectness and even (in some cases) silent address space corruption that will then manifest itself in all kinds of weird issues later on during the program run. The direct counterpoint to this is that: Any assertion that validates a runtime invariant can (and IMO should) be converted into a test which covers that same invariant, with coverage information proved by tooling. This is possible unless the underlying design of the system under test is such that it prevents adequate testing, or your approach to testing is lacking. If you have those problems then asserts are a band-aid on broken practices. Moving quality checks to the left (design / compile time, not runtime) is a generally beneficial practice. Put another way, I've seen many bugs which should have been caught cheaply early with adequate testing practice, rather than at runtime where they caused system failures. It's a rare bug that I see that that isn't the case. Perhaps there are points where this broad recommendation doesn't apply. Safety engineering might be one of those, but the problem space of selling someone a widget over the internet rarely has that same level of need for runtime invariant testing that sending a rocket to space might. --- On a different side of this, I do think that system level assertions (i.e. real code paths that result in actions not `debug_assert!` calls which result in crashing) can belong in systems to check that some process has reached a specific state. I prefer systems to be designed that don't (provably) crash ever. --- A third side to this is that assertions are code too. They are a place which is rarely if ever tested (and is generally impossible to test because they cover invariants). This means that they're an unmitigatable risk to your system. A thought experiment for you, what if LeftPad[1] (instead of being deleted) added an assertion that the total number of characters was < 10. Removal caused a bunch of pain for devs. Assuming that this change rolled out through development chains as normal, this change would have broken many runtime systems, and would have been much more costly. [1]: https://en.wikipedia.org/wiki/Npm_left-pad_incident https://en.wikipedia.org/wiki/Npm_left-pad_incident