http://d.puremagic.com/issues/show_bug.cgi?id=6857

It seems we can't all be agreed on how it should be.


It seems part of the problem is that there are two views on the essence of an in contract in an OOP context:

(a) it is part of the API of the class and, as such, a specification to which any user of the class must conform

(b) it is a means of verifying that the target object can handle the input being passed into it

Current D takes view (b), by checking the in contract according to the actual class of the object - dynamic binding. Several of us (myself included) have argued on the basis of view (a), that it should be checked according to the compile-time type of the object reference - static binding.


So far, there have been arguments both ways.

Arguments in favour of static binding:

s1. A user of a class A, in the general case, doesn't know whether something of type A is a plain A or something of some subclass of A. This is part of the OO principle of encapsulation. As such, it doesn't make sense for the class user to rely on the widened preconditions in subclasses it doesn't know about. (But see d3.)

s2. As such, it helps detect more bugs in code that uses a class of which programmers are likely to create subclasses.

s3. Obeys the Liskov substitution principle.

s4. Consistency with the inability of a base class user to call methods that exist only in a derived class. If a subclass introduces a new method, that new method doesn't exist from the base class's point of view. In the same way, if a subclass introduces new legal arguments to a method, those new legal arguments don't exist from the base class's point of view.


Arguments in favour of dynamic binding:

d1. It's part of how overriding is meant to work, per OO principles. A method call is resolved through the virtual method table of the object's actual class. (But this is based on the premise that an in contract is just another method. Which it isn't. An in contract is a specification of what is a legal call of a method, quite a different concept from the method itself, which provides functionality to the class.)

d2. Bertrand Meyer's book explains why this is the way in which it must work. (But the truth of this claim has been challenged.)

d3. It allows inputs not allowed by the base class contract to be passed in under controlled conditions - conditions in which some other method is defined from whose return value the legality of some input can be determined. Example provided by Walter himself:

    class A {
        void foo(int x) in { assert(x > 0); } body {}
        int bar() { return 1; }
    }

    class B : A {
        void foo(int x) in { assert(x > -2); } body {}
        int bar() { return -1; }
    }

    void fizzbuzz(A a) {
        a.foo(bar());
    }

(While I can see this being useful, it doesn't change the fact that fizzbuzz is asking the class A, not the class B, for the method foo. And the A.foo contract could just as well have been written
    in { assert(x > 0 || x == bar()); }
thereby causing the call to conform according to view (a) above, hence (d4 aside) enabling static binding to be considered without this getting in the way.)

d4. Now that D behaves in this way, there is going to be code out there that does something like the example in d3. Changing to static binding would break this code. (This seems the one argument for dynamic binding that I'm inclined to agree with.)


deadalnix has pointed out that design of OOP doesn't say anything about contracts. In which case any claim that the whole OOP paradigm takes either view (a) or view (b) is nonsense.

Maybe what's needed is a clarification in the spec of which concept of an in contract (view (a), view (b) or something else) D intends to implement.

If (a), then we need static binding. But how do we deal with the code breakage pointed out in d4?

If (b), then we need to stick with the current dynamic binding. And people taking view (a) will still complain about it. But a clear spec on the issue would at least be something to which people complaining about (a) can be pointed.

Stewart.

Reply via email to