On 11/09/10 08:18, Jay Byrd wrote:
Contracts do not belong to function pointers or any other
dynamic state -- they apply to the invoker, and thus the static type.
Isn't that obvious?

In fact, it is yet one step more complex than that: as the name itself suggests, contracts are "between" the caller (static type) and the callee (dynamic type). Theoretically, the type system has to ensure that both sides are able to fulfill their part of the contract.

The dynamic type must be a subtype of the static type (including equality). In subtyping, in-contracts may be weakened, out-contracts may be strengthened (in other words, a subtype may require less and promise more).

This is all fine, theoretically sound and easy to handle in a clean way for object oriented design as it is done in Eiffel.

The complication in D are function pointers and delegates (FP/DG). For a clean design, the type of a FP/DG would need to include contract information. Contracts are part of the interface and a FP/DG would have to include this. Obviously, this would make FP/DG syntax rather awkward. Furthermore, FP/DG assignments would need to be type-checked at compile time, so contract compatibility would have to be checked at compile time as well. This would be completely impossible.

I conclude that within pure OOP, contracts can have strong compile-time support. In-contracts should be checked by the caller, out-contracts by the callee and both checks could be eliminated if the compiler can verify at compile time that they are fulfilled. With FP/DG, this breaks down and I believe the best one can do is to implement contracts as run-time checks in the callee, just as it is done in D.

The only detail that I would wish for is a more fine-grained tuning of DbC contract checks in the compiler and a clearer conceptual separation of the concepts of assertions and contracts. However, the former is an implementation detail and the latter has been discussed to death before.

Reply via email to