Question

When I override functions in D with "in" contracts, then the inherited "in" contracts are checked. If they fail, then the overridden "in" contracts are checked. If I don't specify any in contract, then it is interpreted as if there is an empty "in" contract. So the following code compiles and runs successfully.

module main;
import std.stdio;

interface I
{
    void write( int i )
    in
    {
        assert( i > 0 );
    }
}

class C : I
{
    void write( int i )
    {
        writeln( i );
    }
}

int main()
{
    I i = new C;

    i.write( -5 );
    getchar();

    return 0;
}

I only want the precondition of I.write() to be checked when I call i.write() since that is what is statically known to be sufficient for I.write() to run correctly by the compiler. Checking all preconditions after dynamic dispatch strikes me as odd from an OO perspective since encapsulation is lost.

I could repeat the precondition or write in { assert( false ); } in all classes implementing the interface, but that's a pain. Is that a design error in the D language? Or is there any proper scalable way to do that?

Was it helpful?

Solution

http://dlang.org/dbc.html

If a function in a derived class overrides a function in its super class, then only one of the in contracts of the function and its base functions must be satisfied. Overriding functions then becomes a process of loosening the in contracts.

A function without an in contract means that any values of the function parameters are allowed. This implies that if any function in an inheritance hierarchy has no in contract, then in contracts on functions overriding it have no useful effect.

Conversely, all of the out contracts needs to be satisfied, so overriding functions becomes a processes of tightening the out contracts.

It is actually a difficult design puzzle when polymorphic behavior comes into question. Look, for example, at this bug report with related long discussion: http://d.puremagic.com/issues/show_bug.cgi?id=6857

Regarding question how to achieve wanted behavior - mixin's always work when copy-paste needs to be prevented, but I am not sure that it is OK to do it from the point of Design By Contract paradigm. Unfortunately, need someones more theoretically competent in this question advice.

OTHER TIPS

A precondition in D is a requirement for the function to run correctly. If you overload the function, you write a new code for it, the old precondition - which is a requirement for the old code - is not necessarily a requirement for the new code.

So this issue, while not directly discussed about interfaces, is http://d.puremagic.com/issues/show_bug.cgi?id=6856

This might be a hard one to get in though, Walter is big on the no breaking changes thing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top