Crash in out contract in interface

Timon Gehr timon.gehr at gmx.ch
Wed Aug 24 09:45:22 PDT 2011


On 08/24/2011 04:47 PM, Andrei Alexandrescu wrote:
> On 8/24/11 6:58 AM, Timon Gehr wrote:
>> So, basically interfaces are the only place in D?/DMD where you can even
>> specify contracts without a function body and there they don't work. I
>> think the bug is not the only problem, actual contracts should /always/
>> be part of the function declaration and not require an implementation to
>> work. Everything else degrades contracts to simple syntactic sugar for
>> assertions.
>
> That plus interplay with inheritance.
>
> Andrei

Well, yes, that is true. Where one can add contracts, they will be
inherited. But inheritance is actually where D's current contract
programming model is weakest:

It should be possible to use inheritance to create classes that move
gradually from unimplemented, but specified to implemented and extended.
The fact that unimplemented methods in an abstract class cannot define
contracts is an unforgivable left-out, because that is where contracts
are most useful: for the specification of what all implementations of
the method are allowed to assume and must guarantee.

Contracts are declarative:
"If you guarantee this, I will guarantee that."

Contracts and implementation are two completely orthogonal concepts,
and there is no reason to couple them in any way. Not allowing
contracts without implementation is like telling a customer "You are
not allowed to specify your needs unless we have already written code
to satisfy them."

Do you agree that this will have to be fixed eventually, when all the 
more important features are fully working?


PS:
I realize that there are workarounds:
- Just provide an empty body. But then you lose the enforcement for
   implementations of that method in heirs of the abstract class, and
   every one of them will have to specify pointless "override"'s that
   make the code less self-documenting. Also, if there is a non-trivial
   postcondition, an empty implementation is just a wrong
   implementation. So this is no solution.

- For every abstract class, write an interface that specifies all the
   contracts for all the unimplemented methods, and let the class inherit
   from it. Considering that this is the most common use case in a sanely
   designed contract programming project, that is not an optimal design
   at all. (and if you do this, your program will currently crash)

- Never use abstract classes but only the NVI idiom. Either you
   declare each method twice, once final with contracts to wrap the
   other, or go to some Eiffel users and let them have a good laugh by
   telling them that in your favorite language, 'deferred' classes and
   contracts cannot be used together, if you don't 'freeze' all
   implemented 'features', and similar stuff. :o)






More information about the Digitalmars-d mailing list