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