Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I don't think the examples you provided differ all that much. Someone might add a new constructor that no longer sets the string fields correctly, or your function might get modified so that it can be passed a mutable structure. Type systems and tests can be used to make it harder for future people to break your invariants, but they can still be broken.


Theres a difference between the user breaking an assumption and a self inflicted breaking change. For starters the former can happen after compile time.


You've chosen a good example to further this discussion precisely because it further emphasizes the differences between assumptions and invariants in code: the point when it breaks. Assumptions break at unpredictable times (like when the machine architecture changes), invariants break when someone modifies the code.

If you or a colleague have modified the constructor NumericString to no longer enforce the invariant that it only includes digits (remember though that utf-8 has more than just the ascii digit characters, we aren't necessarily talking about ASCIINumericString) but can include hyphens, a reviewer should have alarms going off in their head: somewhere in the code surely some conversions to numbers is going to fail without further manipulation. That is the benefit of an invariant, it is a part of the code by construction and enforced there; the purpose of reviews and the purpose of encapsulation and strong typing is to narrow the boundary where the invariant must be enforced.

Assumption on the other hand have no narrow boundary. Memory size changes, what part of your code is no longer valid? It is potentially unbounded if your code was allowed to rely on something that was not enforced.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: