Why Is "Design by Contract" Not More Popular?
Coryoth writes "Design by Contract, writing pre- and post-conditions on functions, seemed like straightforward common sense to me. Such conditions, in the form of executable code, not only provide more exacting API documentation, but also provide a test harness. Having easy to write unit tests, that are automatically integrated into the inheritance hierarchy in OO languages, 'just made sense'. However, despite being available (to varying degrees of completeness) for many languages other than Eiffel, including Java, C++, Perl, Python, Ruby, Ada, and even Haskell and Ocaml, the concept has never gained significant traction, particularly in comparison to unit testing frameworks (which DbC complements nicely), and hype like 'Extreme Programming'. So why did Design by Contract fail to take off?"
It mentions the word contract, and as Mike TV's dad said "contracts are strictly for suckers"
Comment removed based on user account deletion
Darl put it best: "Contracts are what you use against parties you have relationships with."
I don't have relationships with random other programmers (even if they are female and cute).
GLaDOS for President 2016! "Well here we are again. It's always such a pleasure." -- GLaDOS, 2011
Who cares if it's popular? If it solves your problem, use it.
My other car is first.
Design by contract seems like a lot of extra work and runtime cost for something that might once in a while catch a bug in already-deployed code. Lighter weight methods like static typing catch (certain kinds of) errors before the code is even compiled; unit testing is usually done before code is deployed, and with the express aim of exposing incorrect behavior in corner cases.
Just what niche is design-by-contract supposed to fill? It's heavyweight, costly at runtime, undirected, and likely to catch bugs only after deployment -- too-little-too-late. Maybe it's unpopular because it's a poor tradeoff.
I employ what is known as "Extreme Programming." It mostly involves alot of screaming at the monitor and yelling at my coworkers. I get fired alot but I never have a hard time getting a new job with my Extreme Programming skills that I write all over my resume.
Agreed fully, but I'll add one half-drunk observation: Fucking Business analysts are bull-shit artists who don't know objects, nor functions if they got smacked in the heads with them. 90% of the time they bill is a complete waste of company money. Also, 60% of 'Architects' fall into the same category.
The force that blew the Big Bang continues to accelerate.
Design by Contract adds more complexity to code, particularly if you're dealing with a language that doesn't natively support it.
Of course, you don't actually need special constructs to check values on input then tossing an exception/returning an error when the data is not in the expected range. In fact, you should go back to remedial programming classes if you're not already doing this.
The last thing you should do is try to figure out what the caller really meant if the value is out of range. Assuming a default works in some cases (which, btw, wouldn't work with Design by Contract as I understand it), but most of the time it's just better to fail and make the programmer fix their mistake.
GLaDOS for President 2016! "Well here we are again. It's always such a pleasure." -- GLaDOS, 2011
If you're serious about design by contract, you need to use a language that supports it. Eiffel does, of course, and so does "Spec#", Microsoft's verifiable variant of C#, but other than that, "support" is a collection of half-baked add-ons that don't provide any strong assurances.
If you're going to take object invariants seriously, you have to take object invariance seriously. Objects can't be allowed to change other than when control is inside them, and when control is inside the object, no public method of the object can be called. This means you have to be able to catch cases where object A calls object B which then calls a public method of A. The invariant of A isn't established at that point, and so, calls into A are illegal. This strict notion of inside/outside is fundamental to class invariants, but many so-called "design by contract" approaches gloss over it. You need a way to explicitly say "control is now leaving this object temporarily" when calling out of an object, and the object's invariant must be true at that exit.
Threading and locking have to be handled in the language. The language needs to know which locks protect what data, or invariants aren't meaningful.
Then there's the problem of how to express an invariant, entry, or exit condition. Are quantifiers provided, or what? How do you talk about concepts like "forward and back pointers of the tree must be consistent"? There's known formalism for that sort of thing, but it's not something you can express cleanly in, say, C or C++.
Without smarts in the compiler, run time checking tends to be too expensive. The compiler needs to know that member function F can't change member variables X and Y, and therefore, invariants concerning X and Y don't have to be rechecked. Without optimizations like that, you end up rechecking everything on every call to every access function.
I'd like to see more design by contract, and I'd like to see it work well enough that when something breaks, you know which side of the interface to blame. I used to do proof of correctness work, and it's quite possible to do this. But you can't do it in C or C++; the languages are too loose. It's been done well for Modula and Java, and a DEC R&D group had a very nice system going just before Compaq canned DEC's Palo Alto research labs. The rise of C killed off verification work; the decline of C may bring it back.
A good business analyst will answer the question "What is it that we (the client) need." They help make sure that the excellent code you write, when it's doing as you were hired to write it to do, solves problems instead of making them.
A good architect will help establish clear separation of authority, giving team members more autonomy to go do what they're good at without having other peoples fingers in their pies or needing to leave their area of scope.
There are a lot of people with pieces of paper from a school that are terrible at these things, and they muddle along leaving wreckage behind them. But that doesn't dismiss the value of having someone competent in those roles when you can find them.
-1 Uncomfortable Truth
+1 accurate description of extreme programming
Game... blouses.
You know the aphorism about how any CS problem can be solved by another layer of indirection -- except the problem of too many layers of indirection. That's what design-by-contract is. Instead of having the intrinsic type-safety checks and the social trust that the code author has run unit tests if necessary and makes the code do something reasonable, design-by-contract formalizes all this and makes you specify conditions on the code manually. That's quite a bit of effort for relatively little advantage. The popular design-by-informal-agreement works almost as well and doesn't have the extra, unneeded layer of indirection.
So very true, but I (generally) haven't seen it. The problem is that people think that one can 'graduate' with the knowledge they need to produce good results. The last module that I worked specked out by a power-point presentation from the business analyst, and when we insisted on 'use cases' the 'architect' started poorly (from our template), and got worse with every function. Sorry, but it takes real experience and insight to properly design a system, the the best never think that they got it perfect. People have a tendency to confuse bluster and arrogance with ability and experience.
The force that blew the Big Bang continues to accelerate.
I thought this was going to be about some deity being contracted out to create humans.
Design by Contract, writing pre- and post-conditions on functions, seemed like straightforward common sense to me.
Yes, it is, and that's why everybody does it. It simply isn't called "design by contract" by most people, since it isn't actually design and isn't a contract. You also don't need language support for it. And people generally do this sort of thing in two parts: some conditions are always checked, but most are only checked in test frameworks.
I feel that the reason why design by contract (DBC from now on) isn't popular is because the entire point of the paradigm is that it doubles or triples your code length without adding any actual information; first, you tell the computer what should be true so you can do what you're going to do, then you tell it what to do, then you tell it what you should have done. That's a lot of typing just to make sure the computer fucks up in exactly the way you told it to.
Admittedly, I haven't programmed much in any language that has built in support for DBC, but from exercises in classes (I'm a CS major) I've found that generally it's sort of a waste of time at worst and a duplication of effort at best.
Regardless, the theory remains: if you can write pre- and postconditions for a function, you already know what the function is supposed to be doing so you might as well have spent your time writing the function and doing something else.
For instance, consider some list class's addElement function, with some (sorta) DBC assertions:
(And I apologize for no indenting, but the tabs got stripped out in preview so I'm assuming they're not there when I post)
Of course, this is an overly simple example and I'm probably not even doing it right; however, hopefully it's close enough that you can see what I mean. All of the assertions are semantically redundant; they don't add any meaning to the code. In fact, I don't think it's possible for that to be true in DBC; if an assertion somehow adds information to the code, it's not an assertion any more.
I'm surprised no one answers thruthfully on this. It looks like everyone wants to appear like they use every technique under the sun and still deliver in time. In my opinion, these methods all cost time and are quite a bore. To top it off, most projects don't require that kind of quality at all.
8 of 13 people found this answer helpful. Did you?
I took a glance at Eiffel a while ago - but mainly with the intent of answering one question: is it checking these contracts compile-time or runtime? It turns out (on page 68 or so of their manual) that it's at runtime.
I don't want my software to fail in the field (at my day job, we write stock trading software - reliability is key because lack of availability can quickly become very expensive). If I could define a number of pre- and post-conditions for each function and have the compiler check these for me, I'd be happy. (Yes, I realise that this is quite a tricky problem of static or dynamic analysis, depending on how far you want to take it.) If the conditions are only going to be checked at runtime, then I'm going to have to write unit tests anyway - otherwise, the failure's going to be beautifully detected and localised and so forth, but crucially, it's going to be one of my customers that detects it. If I'm writing unit tests anyway, why bother with DbC?
When there's a DbC language or add-on that checks the contracts at compile time, I'll be interested.
PenguiNet: the (shareware) Windows SSH client
DBC has a greater requirement towards designing everything up front.
XP allows you to be more flexible in your approach, and supports the need
to constantly refactor your code.
In my experience, at the start of a complex project, we are never sure of
all the answers. The ability to pull together small pieces, to constantly
refactor as we learn more and to work in a close team outweighs the
big-systems sort of approach where everything is specified to the last
detail before you start.
Tried both, DBC stuck in the throat.
As has been noted, most programmers already do design-by-contract, they just don't call it that. They call it argument checking. The first thing most routines do is validate their arguments, and return an error if any of them are invalid. The last thing done is to check the results and return an error if the results aren't valid. The calling code then checks for error codes or invalid results (eg. a search function returning a null pointer indicating the item wasn't found).
In the real world I often skip this overhead when the conditions are enforced elsewhere. For example, a data structure needed by an internal function may not have to be checked for existence since if it hadn't been created my initialization function would've detected this and signaled an error and the program would've exited. In cases like that, I either omit the check or wrap it in an ifdef so it's only done during development and ignored by the compiler during the release build.
Don't make the mistake of confusing the name of a concept with the concept itself. You'll find quite often that that nifty shiny-new concept someone's presenting as their own has actually been around for 30-40 years and they've just added some chrome, filed off the serial numbers and changed the name to keep you from noticing this.
assert(condition) is your friend. It's not called a contract, it's not design (but a very good practice!) and it does the job well.
I do some teaching on an Open University course here in the UK which uses the concept, and my experience is that many students, including experienced programmers, find it difficult to do. Common errors include:
- confusing the signature of the function (in terms of the types of permitted input) with the pre-condition. It may be true for some implementations of pre-conditions that you need to include information of the form "input is a string" but it isn't for the way we do it in the course.
- ignoring input cases (e.g. giving a post-condition which only makes sense when the input is a non-empty string, but using a "true" pre-condition); students know theoretically that every possible permitted input needs to have an appropriate output in the post-condition but can't put this into practice
- difficulty in creating conditions which are precise; this is both in the early part of the course, which uses English language conditions, and later on when algebraic conditions are introduced
- designing tests which use inputs which fail the pre-condition (which is partly because the testing tool used in the course doesn't check the validity of the pre-condition, so invalid inputs can produce sensible looking outputs)
- confusion between pre- and post- condition rules: they often want to restrict the input by changing the post condition
It seems to be the case that it is at a particular level of abstraction vs practicality that many find difficult to cope with.
You can rent this space for $5 a week.
Apart from "it's too hard", I think Unit Testing has overtaken DbC as an approach.
/ DbcAndTesting.html and particularly the postscript.
- You can write unit tests in any language, with or without a framework. (I saw a "mini-framework" for C that consisted of three macros and a coding convention.)
- In a test, you can specify assertions before and after each method call. It's a little more tedious to represent classic DbC assertions, but the Abstract Test pattern among others allows you to collect common code.
- You can strip out assertions in production code simply by leaving test code out of the product.
- Unit tests also run scenarios automatically, without an extra "test driver".
The one thing Unit Testing *can't* do is check production code as it's running. On the one hand, that's great at catching conditions you never thought of. On the other hand, customers tend to get annoyed if their app shuts down. I'm sure there's some work on partial in the Eiffel world, but so far I haven't seen any.
See also http://onestepback.org/index.cgi/Tech/Programming
They do, yet in my experience, these things are inversely correlated. This applies to all guidance/oversight roles, including business analysts, software architects, consultants, and indeed managers themselves. As I've commented here before, you can always identify a good leader by three characteristics:
The third one is usually the easiest way to identify morons. If you come across a leader in software development who places more value on reports and metrics so they can track things than they do on supporting the developers and test teams working for them, then you know you're dealing with an incompetent.
And yes, that does mean many leaders in software development organisations today are incompetent. That's why the genuinely good people are worth so much.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
We call it include files and C coders have been doing it for ages. You noobs and your silly OO languages.
Glass
A lot of functions in real world programs just don't fit this model. Especially in GUIs. Or functions that manipulate internal data structures. Only the most trivial programs (or contrived exercizes of academics) strictly fit the functional, no-side-effects model for all functions. And if you can't apply this method to your entire program, you are going to find a more flexible way to verify behavior.
Those people who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)
Sure, but so do writing explicit interfaces to modules, writing unit tests, and for that matter, writing comments. It's just a question of whether introducing that complexity at the time you write (and maintain) the code brings compensating benefits down the line.
Only a small proportion of development time is typically spent physically writing code, so these defensive programming techniques can be used pretty much on auto-pilot. The implementation costs are therefore relatively small. Given that they can prevent many bugs or save much time during later development, I would argue that they are well worth adopting, unless you already have something in place that provides similar benefits via some other means.
(This isn't to say that the parent poster's point isn't valid, or that aiming to keep your code as simple as possible is a bad thing, of course.)
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
I'd agree with much of your post, but I think there's an unwritten assumption about programming style in what you wrote: you seem to be restricting your scope to imperative languages with mutable state (talking about locks and threading, for example).
If you're working in a language that doesn't permit generally mutable state, it's much easier to use concepts of design by contract, essentially because all you have to do is check that when you've finished constructing a new value, it is valid for whatever type it has. Of course, such languages have disadvantages as well.
I suspect that a great deal of work in programming languages over the next few years is going to focus on how to identify and localise side-effects more explicitly. Pure functional languages that don't allow mutable state at all seem to be quite inefficient, and have fundamental problems for high performance applications that have yet to be resolved. Things like the monads widely used in Haskell today provide some powerful features like mutability but built on a much sounder base than many of today's imperative languages, but at the cost of horrendous syntactic overheads, which kinda spoils one of the big advantages of adopting a functional language: conciseness.
However, multi-core and multi-processor machines are fast becoming mainstream, and loose imperative programming languages have failed to provide satisfactory tools to take advantage of these architectures. I expect this to drive a general move towards more declarative rogramming styles in the industry. Meanwhile the academics, who have seen it all before, will be working on more powerful models of scoping and side effects, well beyond the glorified block scope/lambda calculus stuff that most of today's mainstream programming languages are effectively built on. Once we start getting programming languages with more powerful ways to signify when it is acceptable for what sorts of side effects (including changes in state) to occur, we'll have the sort of foundation needed for your ideas about being inside/outside an object, and compilers will have the sort of framework needed to optimise DbC checks so they're only applied when they're really needed and don't carry unfortunate performance penalties.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
I know what Design by Contract (played with it while at school), but as the poster of the article and other comments have pointed out, there isn't much real language support out there. However, unit testing is something I've been told to do; rather than having informal test cases, I wound up writing a fairly formal testsuite for a library I have written that tests every code path a few times. While doing them, I uncovered some funny results that I might not have otherwise saw, which is great, because it formalizes things and there is a proof that it works.
Quality. What makes you think most projects don't need that kind of quality? You realize how much crap code is out there? If I got an XML/RDF parser I expect it to parse things correctly and tell me when something is not right with the file, and not silently miss/omit something which makes me question my own code and wasting my time because it's not in my code. If I have a multimedia file encoder I want the files generated fits the spec so it can be played by other players that follow the same standard. If I have a web browser I expect it to render things right and not have any security violations. Web applications - I expect all inputs to be checked, no SQL injection or cross site scripting permissible. If you say there are many projects that don't require that kind of quality, how about giving some examples.
Right, cost and time issues. Sure, it makes development potentially twice as long therefore twice the cost, but wouldn't not having customers coming back saying the code doesn't work, or it broke, translate into savings? For open source stuff, why not spend time to make things correct and have a proof of it to increase your reputation? There are no good reasons not to have some sort of unit testing in place in any code (or binary - test cases for the code that created the binary) that is to be released for public consumption.
Please direct all bug reports to
Most programmers aren't interested enough in technology to even know what Design By Contract is.
---------
There is inferior bacteria on the interior of your posterior.
Fixed
Ask the people who actually use the stuff next time.
See, now that wasn't that hard, was it?
(yes, i do know what DbC is, but this is how we were taught DbC in college... shocking isn't it?)
To do DbC, you have to have a contract first. That means you know exactly how your function is supposed to be called and what values are valid, etc. Now trace from one function to its caller, and to it caller's caller, etc, and eventually you either reach the user interface or some business logic. Knowing how the user interface and business logic calls other functions and what values are valid means you have a complete set of user requirements on hand.
Now, I don't know about you, but I have never seen a project with a set of user requirements at the beginning of the project that remains the same at the end of the project. I.e. either they are incomplete to be begin with, or they change in the course of the project, or both. So that means any "contract" you added into your code is likely to become wrong during the course of the project, rendering it more an development obstacle than a development aid.
In contrast, XP and other "Agile" approaches recognizes and accepts the fact that requirements change, rather than hoping in vain to nail the requirements down.
Oliver.
> assert(condition) is your friend.
And assert(condition && "Explanation of why it's bad and what to do to fix it") is even better. Don't make me read your code and figure out why the hell you put some obscure assert(n != 455) in there.
That's what business analysis is, going around asking people and writing it all up in a report. You think the executives that are signing the contracts and paying the bills know what the people on the ground need? They're salesmen, they don't.
-1 Uncomfortable Truth
Design by contract, like most formal method approaches, doesn't scale to interesting levels. If you are working on a 200KLOC project on a tight schedule, the last thing you can afford yourself is increasing time spent per line of code by equipping classes, loops and methods with pre & post conditions. And you would need to do this on a substantial scale to make a significant impact on overall quality. I'm sure most projects could boost quality significantly if you double their budgets but then doing so is unacceptable in most real life situations. Good enough involves balancing a lot of factors and quality is just one of them.
It's great if you can specify that a piece of code is a 100% correct implementation of a given specification but in real life the requirements are sketchy at best & keep changing during development. So, you are likely to end up with the wrong system if you don't adjust your interpretation of them to reality during development. Besides, pre and post conditions need maintenance too if you are doing maintenance on your code, so effectively they increase the cost of what is the single most expensive development activity already: maintenance.
Besides there are other, much more useful tools for improving code quality: unit testing, integration testing, static code checkers, compile time type checking, inspections & reviews are all part of the toolkit of an experienced software engineer and largely remove the need for more formal approaches. Additionally clustering and redundant setups are a far cheaper way of guaranteeing uptime than proving the system to be correct. Risk management is better than trying to avoid risk at all cost.
And finally, the value of 100% correctness is overrated. Most commercial software functions acceptably despite the approximately 10 bugs per kloc. In theory disaster could strike any second, in practice it is a rare event that it does and the consequences are quite manageable usually. Of course things do go spectacularly wrong sometimes and usually people then find out a lot was wrong with the overall development process aside from not applying design by contract. So even then, the added value of design by contract is very questionable. You can't compensate for general incompetence with a couple of pre and post conditions.
Jilles
I'm not a DBC expert but when developing and designing projects I OFTEN use this paradigm when two or more developers are working on code. We separate the work that needs to be done and create "contracts" (in java we just use stubbed out classes that return dummy data) so that we can both work in tandem and integrate later. If the project is larger and involves web services there is the obvious WSDL contract that is always negotiated before-hand. If you're building your web-service and generating your wsdl then you've made a choice not to negotiate your contract and hopefully are not a very large producer because small changes in your framework could cause your clients to be forced to upgrade (this isn't a large application best-practice).
Design by contract did, in fact, take off. Almost every language in the list given is older than DbC; it's not in those languages for lack of a time machine, simple as pie. In other news, many languages now include contracts as a fundamental part of the language, and as the article author points out, libraries are available to hack contracts into just about every other major language.
If by "take off" you mean "why isn't every programmer doing it," well, for the same reason that every programmer doesn't do other things they should be doing, like API documentation. Many programmers are lazy, poorly trained, or think it's not worth the time. Some programmers believe in alternatives to contracts, or think contracts are destructive. Some programmers would insist that contracts have been a fundamental part of C/C++ since day one, in the form of ASSERT().
Programmers are (barely) people. There's nothing we all do. Contracts are one of the most popular methods for testing things. Why are unit tests and regression tests more popular? Because it's easier to see what value they provide, if you've never used any testing. They're not better or worse; they're just easier to understand from a position of being a novice.
Contracts are more common than for which you give them credit.
StoneCypher is Full of BS
It is little more than glorified validation, such as IF statements that check input parameter ranges, etc. I don't think we need to add every new fad feature into languages if existing constructs already can do it.
Table-ized A.I.
Most projects are RAD, and as such, there's no time/room/whatever for DbC.
Don't fool yourselves. Even if the code is supposed to be into production it'll still end up being RAD, no matter what the design gooroos tell you how it should be.
As the famous quote goes: "In every project, it eventually becomes time to shoot the engineers and begin production".
Think I'll make that my sig.
In the course of every project, it will become necessary to shoot the scientists and begin production.
I've seen this over and over again -- most programmers have no idea what DBC is. If the language they used supported it natively, they would probably have learned it, but otherwise they will have no idea what it offers.
I think contracts are one of those things that seems to make sense when they are applied
... putting it in some class, giving it a good name, naming the parameters, implementing the function... I am just doing it!! I am NOT thinking about pre/post conditions such as "loan amount > zero" - So this is one reason, we just don't think this way.
... Seems pretty straightforward, get me a collection of expired Subscriptions...What kind of Contract would I use....
to very simple example problems such as the oft used Account class with debit/credit/transfer methods.
The real test is whether the technique/methodology still makes sense when you are writing code on an actual project. Take test driven development, at first apply this can take some getting used to - for many (like myself) it is getting use to writing any tests at all!!!! But really, at its simplest TDD is asking you to do something that you should already be doing, only with more opinions on HOW and WHEN to do it. So it works.
Design By Contract on the other hand is something quite different. Firstly, for the most part we humans do not think in terms of contracts or pre/post conditions. We might use contracts for some things - contracts that most of us never read nor understand, I might add - but for the most part I think we operate by assumptions - we don't think about a list of pre conditions before doing something and then a list of post conditions after doing something...like they say at Nike - we Just Do It.. This is not to say that the pre/post conditions don't exist - they do - but we only notice them when their violation causes us some obvious consequence - like oops, my account is over drawn! So when a developer is writing code this same type of thinking is in operation.... I need to code a function that returns a loan payment amount for a given interest rate, loan term, and loan amount - I first think about the formula that calculates this and coding it in my favorite language
Secondly, in real systems that much of the code just doesn't lend it self to being described by pre/post conditions.... Subscriptions.get_expired()
pre-conditions: Are there none?
post-conditions: All returned subscriptions are expired.....hmmm seems to be stating the obvious....
Here are several reasons why DbC has not caught on, ordered descending by importance:
1. Writing a contract is often just as difficult as writing its implementation, with the same potential for mistakes. Also, there seem to be no guidelines whether contracts for higher-level procedures should repeat some of the stuff already present in contracts for lower-level procedures which they invoke. The required case-by-case decisions are arbitrary and annoying.
2. Lack of language support. Without language support and inheritance, you will be forced to copy-paste contracts, increasing the risk of inconsistency. Unofficial language extensions like JML do not integrate well with development tools.
3. Lack of education. DbC is relatively unknown, increasing the risk that future maintainers will be baffled by your code. DbC requires deeper understanding of OO and a more systematic approach than informal unit testing.
4. Personality of the inventor. Meyer's strong opinions and attempts to push Eiffel/DbC onto the market made other academics hold back their endorsement.
Creators and maintainers of code, ever what you want to call them (programmers, developers, software engineers, saboteurs...), are just like other folks, really. If you make available to them a tool which enables them to do their jobs "fbc" (faster/better/cheaper) according to how they want to or have to do their jobs, they will be all over that tool like flies on used dog food. Alternatively, like so many other purported improvements to systems which claim to enable fbc work (usually promised in toto, not at the moment at hand), DbC is additional overhead (viz., "more work") for the individual at the moment (which is how adoption decisions are made).
I have seen many laments about supposedly great systems not being adopted. Most seem to me to really be complaints by someone that others don't want to work the way s/he would like them to.
Folks are smart. If something is an improvement, adoption happens.
A little research on the part of the OP might have turned up the following fact, pretty well known to those of us who are familiar with the technique, from Wikipedia: Design by Contract(TM)" is a trademark of Eiffel Software, the designers of Eiffel.
So the short answer is, DbC is extremely common, but it can't be called that by anyone but Bertrand Meyer and his licensees.
On the other hand, from my experience writing good unit tests gives you most of the benefits of DbC and a whole bunch of other benefits that DbC doesn't give, so of the two, I'd rather spend my time writing unit tests.
I think the main reason DbC isn't more popular is the approach that most programmers take to programming: getting the computer to do something. When you write a program, most think about what they want the computer to do when it is done. This is why imperative languages have flourished while functional and logic languages marginalized. Coming up with valid and useful contracts is mental work that doesn't get you closer to usable code, especially in a Less Is More world.
If, on the other hand, you do a complete analysis of the problem, build a conceptual model of the entities and operations involved, and code to that, then you are getting closer to the realm of mathematics, and DbC might be for you.
The middle ground is where we get things like type checking, objects/classes, a variety of code analysis tools, and probably a pile of things I've forgotten or I'm unaware of.
In contrary to the authors post, languages like C++ / Java etc. do not support design by contract.
To have DbC you need to use 3rd party tools and ugly hacks. That basically means 2 compile steps, one where the standard compiler compiles your source language, e.g. Java, to byte code, and a second step where the extra tool analyzes the source code, the comments or the annotations and enhances/augments the byte code then.
OTOH, test driven development or Extreme Programming where the focus is on having so many tests that every single method is tested, basically are exactly the same as DbC. It does not matter for the ordinary developer wether he can write his pre- and postconditions directly inside the code, or if he has a test which checks the pre-and postconditions in well defined test harnesses.
OTOH, as soon as Java has pre- and postconditions the language only needs 3 more things: multiple inheritance, templates and operator overloading.
angel'o'sphere
Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
The first thing most routines do is validate their arguments
Let me modify that just a little bit: "The first thing most routines should do is validate their arguments."
A large majority of the security and stability problems we see in software occur precisely because (lazy|busy|rushed|incompetent) programmers didn't do this. When you're faced with that problem having the language force you to do the right thing can be helpful.
Also many languages don't have all the right tools to make argument checking easy. I find this easiest with languages like Perl which excel at matching, but doing the same task in ANSI C might take 10x the LOC.
I know *I* write better code when Java makes me catch exceptions, etc. - I admit to resembling the above group of programmers at times. Note to self: go check out the java version of design by contract again...
My God, it's Full of Source!
OUTSIDE_IP=$(dig +short my.ip @outsideip.net)
If I had a sig, I would put it here.
The party to the contract with all the power never wants to abide by their side of the contract.
Often, but not always "management".
The problems is that developers, users and managers all speak somewhat different languages. It's all English but they all see things in a different way and that leads to confusion. In general developers should spend a considerable amount of time with the users in their domain to really understand the needs of those users.
Case in point, I worked for a CAD firm and our developers would be sent to different companies to observe how the engineers use our product. We would invite many of those engineers to our headquarters and let them just spend time with the developers. It worked great, especially as far as the user interface of our systems was concerned. To an average non-engineer Joe it would look totally ugly and counter-intuitive but the engineers (our real customers) loved the user interface. When the company was bought out and new management came in they decided to single-handedly change to interface to make it more Windows-like. It ended up sucking and every single real user of our product hated it and refused to upgrade to the new version. The company went downhill after that. I quit too...
DbC failed because it was tied to Eiffel.
You can do XP with any language.
Also unit testing can do the same thing as DbC. Don't want null to be passed into a function? Make a unit test to make sure it doesn't happen.
Indeed. "use cases" alone totally suck for stating requirements. Give me a good old-fashioned SRS or SDD anyday.
Unfortunately Mr. Meyer runs up against the halting problem. If the definition of a function, or the contract, says that a parameter must never be the NULL pointer, there are two choices: the code must check whether that pointer is NULL, or it must be proven that that pointer can never possibly be NULL. The second is, with the current state of the art, impossible no matter what language constructs are around to help. That means the check has to be done, the only question is whether it's done by the caller or the called function. And the first rule I learned is to eliminate redundancy, which means that given a choice of doing a check in one place or doing it in a large number of places you do it in the one place.
Design by contract is many things, a large number of them good, but it is not a replacement for error-checking.
They do, yet in my experience, these things are inversely correlated. This applies to all guidance/oversight roles, including business analysts, software architects, consultants, and indeed managers themselves. As I've commented here before, you can always identify a good leader by three characteristics:
The third one is usually the easiest way to identify morons. If you come across a leader in software development who places more value on reports and metrics so they can track things than they do on supporting the developers and test teams working for them, then you know you're dealing with an incompetent.
And yes, that does mean many leaders in software development organisations today are incompetent. That's why the genuinely good people are worth so much.
I couldn't agree with your three characteristics more, (or the parent poster's opinions as well), which is why, as a business analyst, I plan to ask for a raise this week as a part of my annual review. Not just the shitty 3% raise mind you, more than 10%. Why? Because I have my B.S. in Computer Engineering, have been doing this job for about 4 years now, HAVE the 3 characteristics of a good leader mindset and do my best to fulfill it (although oftentimes not wonderfully), and yet I'm STILL better than half the people I've ever met doing the 'Architect' or 'Business Analyst' job descriptions, because as you say, the good people are hard to find. Arrogant of me to consider myself "better than the rest"? Maybe, but if my management accepts my raise request, then either I am better than most, they're more clueless than most, both, or neither (I am a moron and they're great leaders). In any case, I figure the worst I could possibly do is to NOT get the raise, in which case I'll likely begin considering other alternatives to this job, or find another way to get my raise. This will have the effect (in my mind, anyways) of either confirming my work at this company, why I'm working for these people, and the way I'm going about doing my work; OR give me pause to consider who I'm working for, how I'm working, and whether it's worth sticking with these people, division, or company. Either way, I win.My point is that, if you're reading this post (or the previous two parent posts), and finding that you agree... well, why are you also not asking for a raise? Quit whining about the job market and off-shoring, and ask for what you want!
I have a math degree and am now taking CS classes. It seems to me that in contrast to mathematics and physics training, the CS curriculum makes computing seem easier than it really is. There's a pervasive "it's simple" attitude that is enabled by focusing on solved problems and simple situations. I wonder if that has anything to do with why inexperienced developers get themselves into trouble with their arrogance.
And let me add that I include many experienced managers in the category of "inexperienced developers." A programmer comes out of college thinking, "Everything is easy; these guys must not be too bright if they're having problems." If he makes it into management without having an attitude adjustment, he's going to blame all his failures on the fact that his developers are missing some wonderful insight that he possesses. Then he grabs onto different fads as ways of making his programmers see the light. If the great new thing is just a repackaging of something he already knows, so much the better, since he already knows everything.