Let F(x)
be a function that calls G(x)
, in which x
must be greater than 0. If G
already does assert(x > 0)
, should F
do it as well?
4 Answers
If F
and G
are functions of a class, then you can put validations on public method which can be called from outside.
If G
is a function which performs its business standalone and F
doesn't care whether x > 0 or x <= 0, then you can put this assertion on G
and doesn't require to check on F
.
If F
and G
are totally different layer functions and F
should care about x, then put this assertion both F
and G
.
Probably. The details depend on your programming language and performance constraints, but in general the caller may not know that G exists, so it's better to receive the error from F, and as soon as possible.
If this is Java, however, you shouldn't check a pre-condition with an assert (which is disabled by default), but with a regular if
.
If it never makes any sense for F(x) to receive a negative x, you should assert in F(x) that x is strictly positive. On the other hand, if within F(x) having x being negative or null can make sense you should "only" add some logic to F(x) preventing it from calling G(x) with an invalid x.
maybe, but possilby as a last resort.
The best solution would be to encapsulate the contract into the type excepted by f... however a type of int > 0 is impossible or difficult to create in a lot of type systems. (you are really getting into the realms of dependent typing to specify this in the type system, though I think Haskell can do it with GADTs)
The second best solution is to check your preconditions with a normal if. You don't really want the precondition check optimized out for release build if you don't need the performance.
The last resort then is to check with an assert, which will then catch any issue in development but will be removed in release.
F
andG
end up being method classes, where this would be applicable.