Code contracts, do you use them?
-
Pete O'Hanlon wrote:
I lap up the attention.
Well, here's[^] your opportunity for more attention. :) Seriously though, I was wondering what your thoughts were on Judah's post - it seems like he brings up some significant issues. Marc
Reverse Engineering Legacy Applications
How To Think Like a Functional Programmer
My Blog
Computational Types in C# and F#I've added my thoughts to that post - and introduced the caveat of thread safety with contracts.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
-
Judah Himango wrote:
- It's a boil-the-ocean proposition. Everything must use Code Contracts (including 3rd party libs!) or you'll drown in false positives.
- It lacks language support. This code will give false positives, warning you that list might be a null reference:
This should only happen if you're doing static checking. If you do runtime checking, you only see the contract checks, so the example you quote won't trigger anything. What I would expect to see here is (assuming that we can only call
DoSomething
after it's had some data added into it).*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
Sure, if you turn off static checking, you don't get any compiler warnings. In that sense, it's hardly better than
if (foo == null) throw new...
What I would expect to see is:
public void DoSomething()
{
Contract.Requires(list != null);
}Why would you expect to see a list null check? List is initialized at declaration to a guaranteed non-null value and cannot be reassigned due to the readonly modifier.
My Messianic Jewish blog: Kineti L'Tziyon My software blog: Debugger.Break() Judah Himango
-
In particular, I was just perusing the Code Contracts[^] class in .NET 4 / 4.5, so I thought I'd take a quick survey of the community: 1. Do you routinely verify the expected parameter values that your method receives? 2. Do you verify post-conditions (you're method is returning something correct)? 3. Do you use the Contract class, or are you happy with Debug.Assert... and its variants? 4. Do you use your own variant, something like the Contract class? Just curious. :) Marc
Reverse Engineering Legacy Applications
How To Think Like a Functional Programmer
My Blog
Computational Types in C# and F#Marc Clifton wrote:
1. Do you routinely verify the expected parameter values that your method receives?
Only at layer boundaries via the classes that are exposed that way.
Marc Clifton wrote:
2. Do you verify post-conditions (you're method is returning something correct)?
No. I do however verify results from other layers.
Marc Clifton wrote:
3. Do you use the Contract class, or are you happy with Debug.Assert... and its variants?
No and no. If I verify something then it remains part of the code.
Marc Clifton wrote:
4. Do you use your own variant, something like the Contract class?
Not any more. I wrote one one time but it just isn't worthwhile.
-
Sure, if you turn off static checking, you don't get any compiler warnings. In that sense, it's hardly better than
if (foo == null) throw new...
What I would expect to see is:
public void DoSomething()
{
Contract.Requires(list != null);
}Why would you expect to see a list null check? List is initialized at declaration to a guaranteed non-null value and cannot be reassigned due to the readonly modifier.
My Messianic Jewish blog: Kineti L'Tziyon My software blog: Debugger.Break() Judah Himango
Judah Himango wrote:
Why would you expect to see a list null check?
And what happens if someone modifies the code and removes the initialisation of the list? As far as turning off the static checking - contracts allow you to do so much more that they do add value beyond simple
if (...)
checking, even if that ultimately is what they produce. For example, object invariant contracts are useful if your class has state that must conform to a particular requirement - invariants are automatically rewritten into your code to make sure you don't break the state. If you have checks that you do regularly in a class, then use an abbreviator. And yes, you've pointed out that you have to write a dummy class for interface checking, but it has saved our bacon quite a few times with our interfaces by allowing us to supply APIs to the client that do the checking for them when they implement one of our interfaces - that's a real timesaver.*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
-
Judah Himango wrote:
Why would you expect to see a list null check?
And what happens if someone modifies the code and removes the initialisation of the list? As far as turning off the static checking - contracts allow you to do so much more that they do add value beyond simple
if (...)
checking, even if that ultimately is what they produce. For example, object invariant contracts are useful if your class has state that must conform to a particular requirement - invariants are automatically rewritten into your code to make sure you don't break the state. If you have checks that you do regularly in a class, then use an abbreviator. And yes, you've pointed out that you have to write a dummy class for interface checking, but it has saved our bacon quite a few times with our interfaces by allowing us to supply APIs to the client that do the checking for them when they implement one of our interfaces - that's a real timesaver.*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
Pete O'Hanlon wrote:
And what happens if someone modifies the code and removes the initialisation of the list?
Then I would expect the contract checker to tell me it's busted. A boon of this tool should be: "tell me when my code is busted." The current state of this tool is: "your code is busted, even if it isn't!"
My Messianic Jewish blog: Kineti L'Tziyon My software blog: Debugger.Break() Judah Himango
-
Pete O'Hanlon wrote:
And what happens if someone modifies the code and removes the initialisation of the list?
Then I would expect the contract checker to tell me it's busted. A boon of this tool should be: "tell me when my code is busted." The current state of this tool is: "your code is busted, even if it isn't!"
My Messianic Jewish blog: Kineti L'Tziyon My software blog: Debugger.Break() Judah Himango
Judah Himango wrote:
Then I would expect the contract checker to tell me it's busted.
And that's exactly what my example does. It tells you when you have broken the contract.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
-
I've added my thoughts to that post - and introduced the caveat of thread safety with contracts.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
Pete O'Hanlon wrote:
I've added my thoughts to that post - and introduced the caveat of thread safety with contracts.
Fascinating! And thank you! Marc
Reverse Engineering Legacy Applications
How To Think Like a Functional Programmer
My Blog
Computational Types in C# and F# -
Pete O'Hanlon wrote:
I've added my thoughts to that post - and introduced the caveat of thread safety with contracts.
Fascinating! And thank you! Marc
Reverse Engineering Legacy Applications
How To Think Like a Functional Programmer
My Blog
Computational Types in C# and F#You're welcome mate. Glad to be of service.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
-
Judah Himango wrote:
Then I would expect the contract checker to tell me it's busted.
And that's exactly what my example does. It tells you when you have broken the contract.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
Quote:
It tells you when you have broken the contract.
But it also tells you it's busted, when in fact it's not busted, right? (Don't you get the error even if you've initialized a readonly variable to a guaranteed non-null value?) I know for certain this wasn't working last year, but maybe they've fixed it. If so, cool
My Messianic Jewish blog: Kineti L'Tziyon My software blog: Debugger.Break() Judah Himango
-
Quote:
It tells you when you have broken the contract.
But it also tells you it's busted, when in fact it's not busted, right? (Don't you get the error even if you've initialized a readonly variable to a guaranteed non-null value?) I know for certain this wasn't working last year, but maybe they've fixed it. If so, cool
My Messianic Jewish blog: Kineti L'Tziyon My software blog: Debugger.Break() Judah Himango
Judah Himango wrote:
But it also tells you it's busted, when in fact it's not busted, right?
Not with a dynamic check. The static check will tell you it's busted, but the dynamic check actually checks the condition at runtime.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
-
Judah Himango wrote:
But it also tells you it's busted, when in fact it's not busted, right?
Not with a dynamic check. The static check will tell you it's busted, but the dynamic check actually checks the condition at runtime.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
Right. That's what I'm saying. If you use the tool, it gives you too many false positives. You solved that by turning off half the tool: turning off static analysis.
My Messianic Jewish blog: Kineti L'Tziyon My software blog: Debugger.Break() Judah Himango
-
Right. That's what I'm saying. If you use the tool, it gives you too many false positives. You solved that by turning off half the tool: turning off static analysis.
My Messianic Jewish blog: Kineti L'Tziyon My software blog: Debugger.Break() Judah Himango
Well, I have used the static analysis in the past, and combined this with Pex and Moles. It was certainly enlightening. But yes, I turn static analysis off - I've been saying that right from the start here.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
-
Well, I have used the static analysis in the past, and combined this with Pex and Moles. It was certainly enlightening. But yes, I turn static analysis off - I've been saying that right from the start here.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
Got it. We must have been talking past each other.
My Messianic Jewish blog: Kineti L'Tziyon My software blog: Debugger.Break() Judah Himango
-
Judah Himango wrote:
Then I would expect the contract checker to tell me it's busted.
And that's exactly what my example does. It tells you when you have broken the contract.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
It tells you at runtime that you called a method with an invalid argument. That is really no different from "if(x == null) throw new ArgumentException("...")", except that anyone who sees that code will go 'huh? What is Contract.*?' and it's an extra piece of learning required for very little benefit.
-
In particular, I was just perusing the Code Contracts[^] class in .NET 4 / 4.5, so I thought I'd take a quick survey of the community: 1. Do you routinely verify the expected parameter values that your method receives? 2. Do you verify post-conditions (you're method is returning something correct)? 3. Do you use the Contract class, or are you happy with Debug.Assert... and its variants? 4. Do you use your own variant, something like the Contract class? Just curious. :) Marc
Reverse Engineering Legacy Applications
How To Think Like a Functional Programmer
My Blog
Computational Types in C# and F#I take contracts out on my coworkers when they fail to meet the contracts specified by the interfaces between our respective parts of the product. Does this count?
Software Zen:
delete this;
-
It tells you at runtime that you called a method with an invalid argument. That is really no different from "if(x == null) throw new ArgumentException("...")", except that anyone who sees that code will go 'huh? What is Contract.*?' and it's an extra piece of learning required for very little benefit.
BobJanova wrote:
That is really no different from "if(x == null) throw new ArgumentException("...")",
Superficially, you're right. If that's all that contracts did, I wouldn't bother with them. However, they provide some really handy ways to do this as I specify here[^] and here[^]. Invariants and Abbreviators are very handy, but the ability to provide contracts for interfaces is the cherry on the cake as far as I'm concerned.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
-
BobJanova wrote:
That is really no different from "if(x == null) throw new ArgumentException("...")",
Superficially, you're right. If that's all that contracts did, I wouldn't bother with them. However, they provide some really handy ways to do this as I specify here[^] and here[^]. Invariants and Abbreviators are very handy, but the ability to provide contracts for interfaces is the cherry on the cake as far as I'm concerned.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
Honestly that all looks horrible and hacky ... and particularly if it is rewriting the IL underneath me I want no part of it. An 'abbreviator' can be written in normal code just fine, it's simply a validation method! Interfaces that are exposed to external APIs to implement are about the only place where I can see that postcondition validation would be useful. But since you can't force external providers to use contracts, it doesn't help you there anyway! Postconditions in general (and invariants are simply a postcondition applied to everything) shouldn't be necessary in your code because you should already know what your code is doing, and each particular operation can be tested. If you need a global postcondition then you can have a method in your test class that checks that part of the state, which you can call in each relevant test.
-
In particular, I was just perusing the Code Contracts[^] class in .NET 4 / 4.5, so I thought I'd take a quick survey of the community: 1. Do you routinely verify the expected parameter values that your method receives? 2. Do you verify post-conditions (you're method is returning something correct)? 3. Do you use the Contract class, or are you happy with Debug.Assert... and its variants? 4. Do you use your own variant, something like the Contract class? Just curious. :) Marc
Reverse Engineering Legacy Applications
How To Think Like a Functional Programmer
My Blog
Computational Types in C# and F#1. Yes. 2. Yes for interface members and abstract members, where the actual logic is going to be implemented in an implementation. Occasionally on a concrete member if the logic is not straightforward and there are specific conditions that are reasonably verifiable. 3. Yes, I use the Contract class. 4. No.
-
Honestly that all looks horrible and hacky ... and particularly if it is rewriting the IL underneath me I want no part of it. An 'abbreviator' can be written in normal code just fine, it's simply a validation method! Interfaces that are exposed to external APIs to implement are about the only place where I can see that postcondition validation would be useful. But since you can't force external providers to use contracts, it doesn't help you there anyway! Postconditions in general (and invariants are simply a postcondition applied to everything) shouldn't be necessary in your code because you should already know what your code is doing, and each particular operation can be tested. If you need a global postcondition then you can have a method in your test class that checks that part of the state, which you can call in each relevant test.
I'm not trying to force you to use them. If you want to remain doing if/then checking then that's fine. And if you use the interface technique, you do force them to use the contracts.
BobJanova wrote:
Postconditions in general (and invariants are simply a postcondition applied to everything) shouldn't be necessary in your code because you should already know what your code is doing,
Indeed you should, but what happens three years down the line when you've left the company and young Harry Intern takes a shot at your code? Oh, and he doesn't run unit tests.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier
-
In particular, I was just perusing the Code Contracts[^] class in .NET 4 / 4.5, so I thought I'd take a quick survey of the community: 1. Do you routinely verify the expected parameter values that your method receives? 2. Do you verify post-conditions (you're method is returning something correct)? 3. Do you use the Contract class, or are you happy with Debug.Assert... and its variants? 4. Do you use your own variant, something like the Contract class? Just curious. :) Marc
Reverse Engineering Legacy Applications
How To Think Like a Functional Programmer
My Blog
Computational Types in C# and F#I am quite sure I missed somthing about the concept of contracts: Violation of contracts cause exceptions, exactly like violation of using code which is not designed to work with values without the corresponding contract with the drawback of splitting location of need of assumption. What are your reasons for using contracts?