Assert(): The Underused Tool for Correct, Safe Code
Assert(): A Modern How To
Assertions are often misunderstood and underused. This article clarifies when and where to use them, covering four key areas: correctness, safety, development, and documentation. It argues that assertions provide 100% value coverage, prevent silent breakage, and have negligible overhead. The author also proposes an ideal assertion API with production and development variants, dynamic messaging, and stack dumps.
A failed assertion is behaving exactly as you intended, it correctly caught an edge case.
- foo42
An overlapping technique (covering some but not all of the circumstances you'd use assert) is to take a parse-dont-validate approach, and essentially encode the fact that an assertion has been applied to a value in its type.
How ergonomic this is will vary by language, but the general idea would be to apply the assertion logic in some sort of constructor, then prevent any operations which would break the invariant going forward. The simplest way to protect this being by making the value immutable where possible.
Users of the value who care about the invariant being true can then specify in their types that they want a non-empty-collection or a foo-id or whatever it may be, rather than asking for the wider type, then asserting.
- iTokio
I love to combine assertions with « restartability ».
If you’re program has entered an unknown, failed state, just restart it from a known state.
Even better if you can divide a complex system in sub modules that can recover independently without bringing down the entire system.
Something like Erlang supervision tree. Or at least a systemd Restart=always service.
if your program is mostly stateless, and « restartable », it becomes fault tolerant, and you can use assertions liberally and easily avoid unknown/bad states.
Invariants can be enforced, and correctness preserved.
But an important question remains when an assertion is triggered, why invariants were violated?
We need to preserve context, and decide to handle or not this case.
That is easy to forget in code that is assertions oriented.
- eps
> Can assertions be used in production?
Yes
> What should I be asserting on?
Invariants
> Can I customize how assert behaves?
It should abort the program, logging the stack and whatever the context you pass into in, printf-style. If it doesn't abort, it just buries the issue of the program being in incorrect internal state. It should never be OK.
- oso2k
It’s interesting that the author lands on an API much like the function signature for TAP (Test Anything Protocol).
ok( conditional, message );
- dicroce
Personally I'm not much of a fan of assert()'s... at least in the language I use the most (C++). It's not that I don't think you should validate the input ranges of parameters to functions its that in general exceptions are better.