> Needing lots of expensive invariants is almost "invariably" (see what I did there?) a code smell.
What's your definition of need? I want a lot of invariants if because I have found it reduces the chance of error. This is also the finding in that Microsoft case study I linked to. The more invariants, the better, and that means making them cheap to write.
> In C++, I've even seen people assert that an unsigned integer was >= 0. You can just feel the quality.
Entirely reasonable in some cases; it's telling me: "this software is not defined for negative numbers". There does exist code that can accept an unsigned number (because it is what callers found most convenient at the time, and casting is wordy) but is defined on negative inputs, and it would not be valid to put that assertion there. Those assertions are to assist future collaborators of your software, and shorter to write than:
// This algorithm is only defined on positive integers
Until one is using a language with real dependent types, I think your specific example is not on the face of it as egregious as you say it is.
> Go has a notation for problems that are never supposed to happen: panic. For other errors, there are return codes.
Unfortunately I do see panic used -- even in the standard library -- as a flow control mechanism also. But yes, I do use panic for this reason, and tend to eschew using recover for convenience in most situations. It is the lack of an idiom to obtain complete clarity as to the nature of the panic that I find mildly irritating.
OK, my response was maybe a little more snarky than I intended. Anyway, I think we are going to have to agree to disagree about the utility of turn off error checking in production.
What's your definition of need? I want a lot of invariants if because I have found it reduces the chance of error. This is also the finding in that Microsoft case study I linked to. The more invariants, the better, and that means making them cheap to write.
> In C++, I've even seen people assert that an unsigned integer was >= 0. You can just feel the quality.
Entirely reasonable in some cases; it's telling me: "this software is not defined for negative numbers". There does exist code that can accept an unsigned number (because it is what callers found most convenient at the time, and casting is wordy) but is defined on negative inputs, and it would not be valid to put that assertion there. Those assertions are to assist future collaborators of your software, and shorter to write than:
Until one is using a language with real dependent types, I think your specific example is not on the face of it as egregious as you say it is.> Go has a notation for problems that are never supposed to happen: panic. For other errors, there are return codes.
Unfortunately I do see panic used -- even in the standard library -- as a flow control mechanism also. But yes, I do use panic for this reason, and tend to eschew using recover for convenience in most situations. It is the lack of an idiom to obtain complete clarity as to the nature of the panic that I find mildly irritating.