You Must Fix Your Asserts (Zig)(kristoff.it) |
You Must Fix Your Asserts (Zig)(kristoff.it) |
I left a little over a month ago, and the status on that was still “soon”. Some bad practices early on are just really hard to dig yourself out of.
https://docs.oracle.com/javase/8/docs/technotes/guides/langu...
And I'm pretty happy with its design considering its age.
Notably this is not a function call and indeed things are not called unless you enable it. Contrast with Zig. So I guess you will only suffer from code bloat if you never enable them.
The tutorial mentions the dangers of side effects. But it also mentions how to use them for more complicated assertions. That's natural since you'll want something like that when you need to check a post-condition.
Programming assertions get joked on because of, ahem.
- Step one: Turn on extra checks in test environments where the stakes are low
- Step two: Turn them off in production (with realistic data because prod eq. reality) to save cycles
And that seems to be partially accurate. However the truly interesting assertions can test complex conditions that might break complexity (Big O) contracts. Like a private mininum function that is advertised as O(1) on account of taking a sorted list. But there is no type guarantee that the list is sorted. So you assert that it is sorted. But that breaks the complexity contract.
Overall I have not used assertions in Java for trivial conditions in like five years. They're better deployd for something more complex than that.
Then there is the whole thing about -- and more topics to be sure -- crashing the whole application or not. That's not necessarily great for us regular Java programmers. However we can (though discoraged) catch AssertionError if we want to.
Java did the right thing for assertions but then completely failed for the analoguous issue when it comes to logging.
I admit that logging is more complex because you often want it configurable dynamically at runtime. But I'd argue that the language should not be in your way if all you need is a compile time decision and the contortions we made for logging to stay low cost when nothing is logged are crazy in Java.
You can pretty easily have a different kind of assert that disappears in release builds (if you want).
fn processThing(thing: Thing) void {
// this function must always be invoked on
// a thing that has already been started
assert(thing.is_started);
// ...
}
I know you mentioned fuzzing earlier in the article but seriously, fuzzing deserves an extra mention after asking me to imagine that.DbC was first introduced in Eiffel but the ideas can be used in any language. See the following;
1) Design by Contract and Assertions - https://www.eiffel.org/doc/solutions/Design_by_Contract_and_...
2) Applying "Design by Contract" (pdf) - https://se.inf.ethz.ch/~meyer/publications/computer/contract...
3) Also see the book; Persuasive Programming by Jerud Mead and Anil Shinde which uses asserts systematically to write the proof along with code.
Finally, DbC using asserts is now even more important with AI generated code since it allows one to map the specification to generated code.