Static versus dynamic binding of in contracts again - trying to set things straight

Stewart Gordon smjg_1998 at yahoo.com
Sat May 5 05:46:49 PDT 2012


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.


More information about the Digitalmars-d mailing list