5

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?

Ralph Tandetzky
  • 22,780
  • 11
  • 73
  • 120

3 Answers3

3

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.

Community
  • 1
  • 1
Mihails Strasuns
  • 3,783
  • 1
  • 18
  • 21
  • I'm not sure if that documentation page is not just outdated. I'd have to look at TDPL to be sure, but there's a bug similar to the OP's issue: http://d.puremagic.com/issues/show_bug.cgi?id=6549 – jpf Jul 27 '12 at 18:34
  • @jpf That's an enhancement request. Some folks want the language changed with regards to this issue. The documentation is correct with regards to the current behavior. – Jonathan M Davis Jul 27 '12 at 18:38
0

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.

Idan Arye
  • 12,402
  • 5
  • 49
  • 68
0

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.

he_the_great
  • 6,554
  • 2
  • 30
  • 28