[Mono-list] Design by Contract

Robert Shade rshade@dvsconsulting.com
Fri, 31 Dec 2004 18:17:21 -0500


This is a really neat design idea.  I originally thought you were 
talking about something like what unit testing is for; but, after some 
research, I see that this is much more.

Just to add my two cents, I think I would discourage the attribute idea.

For one, it would mean that your compiled application would have to link 
with your DBC library.  This would mean that the user would have to deal 
with a bunch of #if's so that those attributes would not be compiled in 
production code. Otherwise, the user would be forced to distribute your 
library with their product.

Secondly, attributes would force the checking to be done by a modified 
compiler.  This would seriously limit your target audience to mono 
folks.  Love mono, but the masses are using Microsoft's compiler.

Finally, I would imagine that adding this (admittedly wonderful) 
complexity into the compiler is not something the maintainers would 
like.  It would also increase the learning curve of someone wanting to 
join up on the project.

I would recommend using an external processor similar to some of the 
tools available for aspect oriented programming.  You'd add the DBC 
"hooks" by some sort of special comments or macros.  The former would be 
kind of nice because you'd still be able to compile it with a regular 
compiler.  The latter would require the user to run his or her code 
through the tool before compiling.  Both could then be used as 
placeholders for runtime checking code to be inserted.

An external tool would also allow you to investigate the code flow in 
ways that the compiler may not.  For example, you could do "process" 
time checking of the code to see if your "contracts" are always 
true/false.  (I belive the MS compiler does this for conditionals)  For 
things that were marked "invariant", you could follow the code flow to 
see if these are modified at any point.  You'd perhaps even be able to 
warn the user under exactly what conditions the contracts would fail. 
If you had that functionality, you would completely eliminate the need 
for the user to have the (runtime) contract checking code present.  The 
user would already know precisely under what conditions errors would 
occur and could add exception handling to take care of it.

/end of brain dump :)

rob

Stephen Touset wrote:
> I've been using C# for quite awhile now, but one feature that I wish was
> available in the language is support for Design by Contract:
> automatically-enforced preconditions and postconditions on functions, and
> invariants on classes.
> 
> Having done some research into the problem, the best approach seems to be
> using attributes. Using statements inside functions works, but induces a
> lot of programmatic overhead; specifically, inheritance rules for DBC
> would need to be implemented manually. Invariants, also, would be tedious:
> code to check against the invariant would need to be added before the
> preconditions and after the postconditions of every function in the class.
> Worse still is that postconditions must be inserted above every return
> statement. This isn't too bad if you insist upon only one return statement
> per function, but for anyone with multiple returns, this becomes tedious
> quickly. And of course, all of these are clear violations of the Don't
> Repeat Yourself rule.
> 
> Attributes seem to be the way to go. The pre/postconditions and invariants
> are, at the core, metadata about the functions and class. The attributes
> themselves would be able to understand their own inheritance criteria, and
> code can automatically be generated to verify the terms of the contract
> wherever needed. Unfortunately, the way attributes in C# are implemented,
> there seems to be no way to practically use them. Reflection may be
> powerful, but there doesn't appear to be a way that an attribute can
> access (or even determine) the function or class that it applies to.
> 
> My initial approach was to use the CodeDom libraries to insert code into
> functions that would be dynamically based upon the applicable attributes,
> and enforce the conditions correctly. However, the inability for
> attributes to access the "calling" class all but cripples this attempt. My
> next thought was to simply have a script which would understand the
> attributes and insert the applicable statements at compile-time. However,
> the need for attribute inheritance quickly caused this approach to become
> unwieldy.
> 
> Does anyone have an idea about how this could be done in a reasonable
> fashion? If so, would anyone be willing to help on the project?
>