I recently discovered Design by Contract (DbC) and I find it an extremely interesting way to write code. Among other things, it would seem to offer:
- Better documentation. Since the contract is the documentation, it's impossible for one to be out of date. Additionally, because the contract specifies exactly what a routine does, it helps to support reuse.
- Simpler debugging. Since program execution stops the moment a contract fails, errors can't propagate, and the specific assertion violated will presumably be highlighted. This offers support during development and during maintenance.
- Better static analysis. DbC is basically just an implementation of Hoare logic, and the same principles should apply.
The costs, in comparison seem to be rather small:
- Extra finger-typing. Since the contracts have to be spelled out.
- Takes some amount of training to get comfortable with writing contracts.
Now, being familiar with Python primarily, I realize that it is in fact possible to write up preconditions (just throwing exceptions for inappropriate input) and it's even possible to use assertions to test again certain postconditions. But it's not possible to simulate certain features such as 'old' or 'result' without some extra magic that would ultimately be considered un-Pythonic. (In addition, there are a few libraries that offer support, but ultimately I get the vibe it would be wrong to use them, as most developers don't.) I assume that it's a similar problem for all other languages (except of course, Eiffel).
My intuition tells me that the lack of support must be a result of some kind of rejection of the practice, but searching online has not been fruitful. I'm wondering if someone can clarify why most modern languages seem to offer so little support? Is DbC flawed or overly expensive? Or is it just obsolete due to Extreme Programming and other methodologies?