Improve "Improve Contract Syntax" DIP 1009
Adam D. Ruppe
destructionator at gmail.com
Sat Nov 4 14:12:08 UTC 2017
On Saturday, 4 November 2017 at 13:59:39 UTC, Jonathan M Davis
wrote:
> I'm very much of the opinion that proper unit tests pretty much
> eliminate the need for out contracts.
I think that sqrt example is just bad. Out contracts shouldn't be
testing specific values, but rather ranges or nullness or other
such things that arguably should be part of the return type, but
just don't fit in the type system for whatever reason.
Consider this:
class A {
A clone()
out(result) { assert(result !is null); }
body {
return new A();
}
}
class B : A {
override B clone() {
return new B();
}
}
void main() {
A a = new B();
A c = a.clone();
}
The `clone` method defined in the base class arguably out to
return a NotNull!A, encoding that contract in the type, but we
can't really do that with D without breaking the inheritance -
where B is statically defined to return B too, since NotNull!B
isn't covariant to NotNull!A the way B is covariant to A. (At
least not with any techniques I can think of at this time.)
So you can't encode it in the return type... but you can encode
it in the out contract for a runtime check.
It also clearly documents that the subclasses must not return
null (and can add their own restrictions to further subclasses).
One problem I have with some of D's contracts right now is that
they are convoluted, ugly code that make for passable internal
unit tests, you can't reasonably display as documentation as part
of the interface.
But regardless, I say you should not think of out as tests. Think
of it as type system extensions.
More information about the Digitalmars-d
mailing list