Become a fan of Slashdot on Facebook

 



Forgot your password?
typodupeerror
×
Programming

Why Is "Design by Contract" Not More Popular? 178

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?"
This discussion has been archived. No new comments can be posted.

Why Is "Design by Contract" Not More Popular?

Comments Filter:
  • Comment removed (Score:5, Insightful)

    by account_deleted ( 4530225 ) on Saturday March 10, 2007 @02:52AM (#18297944)
    Comment removed based on user account deletion
  • Contracts (Score:2, Funny)

    by VGPowerlord ( 621254 )
    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).
  • Who cares? (Score:3, Insightful)

    by jrockway ( 229604 ) <jon-nospam@jrock.us> on Saturday March 10, 2007 @03:11AM (#18298012) Homepage Journal
    Who cares if it's popular? If it solves your problem, use it.
    • Re: (Score:2, Insightful)

      by heinousjay ( 683506 )
      You win the topic. Everything else is masturbation.
    • Re:Who cares? (Score:5, Insightful)

      by Just Some Guy ( 3352 ) <kirk+slashdot@strauser.com> on Saturday March 10, 2007 @04:03AM (#18298176) Homepage Journal

      Who cares if it's popular? If it solves your problem, use it.

      Two reasons: first, the more people use it, the wider it will be supported. It's nice to be involved with something on the upswing that more people are interested in than bored with. Second, it's nice to know why something's unpopular. Maybe it's hard to use, but you're a genius and will be able to put it to work. Or, maybe, everyone else realized that it's awful and moved on to something less heinous.

    • by rednip ( 186217 ) *

      Who cares if it's popular? If it solves your problem, use it.
      Key word is 'if'. Also only 'if' one designs the contract perfectly, and only 'if' one is able to test it to perfection.
  • by majiCk ( 264238 ) on Saturday March 10, 2007 @03:12AM (#18298018)
    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.
    • by barrkel ( 806779 ) on Saturday March 10, 2007 @03:35AM (#18298090) Homepage
      In a phrase, the niche is professional coders, rather than hack-a-day cowboys.

      Assertions, whether invariants, preconditions or postconditions, can be viewed as extensions to the type system [1]. Since they are expressions of a boolean type and don't modify state (at least, no sane ones would mutate state), they're very easily analysed.

      Combine that with a runtime like .NET or the JVM. Compilers and analysers can use such contracts to perform extra typechecking of e.g. arguments to methods, where the methods have preconditions. "Runtime cost" doesn't exist if the runtime has support, especially where verification also exists. Consider the old conundrum: do you check your parameters, or do you expect your caller to check the arguments before they're passed? What if the parameters being wrong leads to a subtle error that manifests later rather than a dramatic failure? With properly stated contracts, these checks can be inserted at the lowest level and automatically propagated higher statically by the compiler or dynamically by the runtime as necessary.

      The niche that DbC is supposed to fill is formalising what is already recognised good practice - stating your assumptions while writing your code. If you have much experience as a programmer, you'll know that it's useful to use assert, ASSERT, or some other feature of your environment at choice places where you make certain assumptions that you think can't be broken. And if you've read The Pragmatic Programmer, you'll know why you'll want to leave those assertions in the final release.

      Most popular languages, such as C#, Java, C++ etc., capture very little programmer intent in their type systems. There's a lot more potential there - preconditions and postconditions can e.g. state that a variable will be in a certain range dependent on the values of other variables, and then automatically detect range mismatches with e.g. loop invariants. Basically, assertions are really useful extensions to the type system.

      [1] For example, consider that a 'requires x != null' constraint and a notional non-nullable reference type from C# or Java, analogous to 'MyType!' in C-w (C Omega):
      http://blogs.msdn.com/cyrusn/archive/2004/06/03/14 7778.aspx [msdn.com]
      • Re: (Score:2, Interesting)

        by Tablizer ( 95088 )
        In a phrase, the niche is professional coders, rather than hack-a-day cowboys.

        I think you are being naive. In the real world they often want as many features as possible with the smallest staff possible. This means that things like formal testing are glossed over. It is an art-form to deliver tons of features on the cheap. Of course, it depends on the nature of the business. If it is the Space Shuttle or medical equipment, then you better spend the extra money or you will get sued up the wazoo. An intr
        • In the "real world" you're right, unfortunately. However, you shouldn't discount it out of hand. The "real world" methodologies you use, like structured programming and object oriented programming were once regarded as ridiculous overheads - but the thing is, they actually reduce programming effort overall by making code more robust. I don't think I've used a GOTO in a long time.

          Someone once said (can't remember who) that making a program was like piling 100 bricks on top of one another, but using OO pro
        • by xero314 ( 722674 )

          In the real world they often want as many features as possible with the smallest staff possible.

          I think you are being even more naive than the parent commenter. What businesses, including governments, want in the real world, is software that produces the most monetary benefit with the least monetary cost over the life of the system. Sometimes there are certain intermediary goals that effect this, but ultimately what I just said is the goal. If your are a software developer and are not attempting this same thing you are doing your client or employer a disservice at best, and at worst stealing. This

        • In the real world they often want as many features as possible with the smallest staff possible.

          I think what they usually want is the best return on investment, which isn't necessarily the same as what you wrote there.

          In any case, I think your entire post is backwards, though I've heard the same argument many times before. If you want to get lots of features working quickly, the only way to achieve it is to do the development properly. Neglecting QA is a false economy, as is dropping other defensive p

      • Re: (Score:3, Insightful)

        by epine ( 68316 )

        In a phrase, the niche is professional coders, rather than hack-a-day cowboys.

        Unfortunately, hack-a-day cowboys gained control of both the house, the senate, and the clone army, so hack-a-day coding practices are now the accepted norm, and people look at you funny when you pinch your brow in abject frustration.

        The problem with DbC is that the benefits are best understood by an examination of the system as a whole, rather than the culturally ascendant analysis that permits the cable companies and telcos to p

    • by Coryoth ( 254751 ) on Saturday March 10, 2007 @06:53AM (#18298634) Homepage Journal

      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.
      DbC doesn't incur any runtime cost if you choose not to bother - any good contract system allows you to turn off contract checking for production code. That is, DbC provides a test harness during testing but needn't do any checking of finished code after testing is complete. Moreover good contract systems like JML and Spec# are smart enough to allow static checking which allow you to catch a whole host of errors before compilation that static types just aren't going to be able to catch. And I have to admit that I am unsure how DbC is "a lot of work" given that you should be writing unit tests anyway, and if you have constraints or invariants then you ought to be checking those with unit tests - writing the constraint as a contract is less work than writing the equivalent unit test. Finally DbC enables testing that for which unit tests of corner cases simply can't compare - by using the contracts as a test oracle you can do automated randomised testing of several integrated units. That is to say, you can automatically generate data to search the input space delimited by preconditions, and use postconditions, invariants, and preconditions of any called code, to test that several units all work together correctly and potentially catch weird interelated corner cases that you hadn't anticipated. Honestly, check out AutoTest [inf.ethz.ch] or Quickcheck [chalmers.se] sometime, they are suprisingly powerful and have found bugs in established production code that had already undergone extensive standard testing.
    • by xero314 ( 722674 )

      Design by contract seems like a lot of extra work and runtime cost...

      DBC in use is actually a lot less work and a lot less runtime cost. DBC, if used properly, produces software that has a much shorter testing and debugging period. Regression testing is much faster as the contract will not have changed on any of the prior built parts. The though that there is a performance reduction effect of DBC, which is what I assume is meant by "runtime cost" is a lack of understanding DBC. There is nothing in DBC that says there needs to be any runtime checking of the contract. In

    • In "Design by Contract to Improve Software Vigilance" (IEEE Transactions on Software Engineering August 2006) the authors prove that, unlike your assertion, there is a lot of bang for the buck. Conclusion:

      It appeared that efficient contracts significantly contributed to improving the quality of the systems, but also that their efficiency is more important than their quantity.
  • by andy314159pi ( 787550 ) on Saturday March 10, 2007 @03:17AM (#18298036) Journal
    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.
    • As a porofessional developer, I find swearing at the monitor and ranting at my coworkers to be pretty effective and as yet, it hasn't got me fired. I have recently joined an XP shop (the company formally known as Connextra) so I could now try the extreme approach you describe.
  • Design by Contract (Score:3, Informative)

    by VGPowerlord ( 621254 ) on Saturday March 10, 2007 @03:29AM (#18298080)
    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.
    • Design by Contract adds more complexity to code, particularly if you're dealing with a language that doesn't natively support it.

      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 progra

    • Perhaps you should read up a bit on DbC as you're confused about its usage. Design by Contract should not be used for input testing!! As Bertrand Meyer states in his seminal "Object-Oriented Software Construction":

      Assertions are not an input checking mechanism ... To avoid a common misunderstanding, make sure to note that each of the contracts discussed holds between a routine (the supplier) and another routine (its caller): we are concerned about software-to-software communication, not software-to-human

      • You should re-read what you quoted. Here, I'll bold the relevant word.

        Assertions are not an input checking mechanism ... To avoid a common misunderstanding, make sure to note that each of the contracts discussed holds between a routine (the supplier) and another routine (its caller): we are concerned about software-to-software communication, not software-to-human or software-to-outside-world. A precondition will not take care of correcting user input.

        It is in fact used for input testing, to make sure that

  • by Animats ( 122034 ) on Saturday March 10, 2007 @03:48AM (#18298140) Homepage

    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#, [microsoft.com] 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.

    • 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 t

    • It's been done well for Modula and Java
      By whom? I'd like to look into it for my Java projects.
      • Re: (Score:3, Informative)

        by Coryoth ( 254751 )

        By whom? I'd like to look into it for my Java projects.

        DEC R&D made ESC/Java (Extended Static Checking for Java) that used a theorem prover and specification annotations to verify contracts. Development stopped, but it is now open source as ESC/Java2 [secure.ucd.ie] which uses JML [iastate.edu] as annotation markup. I actually listed this as the Java DbC implementation in the article description.

  • Too many layers (Score:4, Insightful)

    by Geoffreyerffoeg ( 729040 ) on Saturday March 10, 2007 @04:06AM (#18298186)
    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.
    • by Coryoth ( 254751 )

      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.

      DbC doesn't force you to do anything. You can say as much, or as little, as you like for contracts (nothing at all if you prefer). The point, however, is to get benefits out of the situation where things can be expressed as a contract. You suggest that writing unit tests to assure code does something reasonable is a good idea, and it is. Writing contracts is no different, and complementary to unit tests if used properly. If your test an be expressed as a constraint then you write it as a method contract or

  • people do (Score:2, Insightful)

    by oohshiny ( 998054 )
    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.
  • Or, in other words, it's because we're lazy.

    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.

    • Re: (Score:3, Insightful)

      by Coryoth ( 254751 )

      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.

      Do you document your code at all? Do you test your code at all? That's all DbC is doing, it is just doing both at once for any tests that can be written as constraints. And remember DbC is as much about other people knowing what a function does as about you knowing - it provides clear conditions for anyone calling your code as to what they must provide, and what they can expect of any returned results, information that, for any decent DbC system, is automatically included in API documentation. You, the ori

      • by Fareq ( 688769 )
        Do you document your code at all?

        Personally, I'd rather read

        {
        // If the array is full, then expand it (or fail if we can't)
        if(full())
        {
        if(expandable())
        expand();
        else
        throw range_error("The array is full, but we can't expand it");
        }

        //add the new item to the position after the current last element
        //and make lastElemen

        • by Coryoth ( 254751 )
          of course there's always:

          require
          not_full_or_expandable: not full or expandable -- require that elements may be added
          do
          if full then expand end
          last_index = last_index + 1
          put(new_element, last_index)
          ensure
          last_index_increased: last_index = old(last_index) + 1 -- ensure length of the array has increased by one
          new_element_added: item(last_index) = new_element -- ensure new_element is the last element
          end

          Of course with a s

          • I'm curious, why did you give your contracts identifiers? Are they treated as first-class objects or am I missing something?
            • by Coryoth ( 254751 )
              Eiffel let's you give contracts names which are then used for documentation and logging of contract violations during testing etc.
        • Actually, in your example I'd prefer the following. (Apologies for losing the indentation; how do you get Slashdot not to do that?)

          if(full())
          {
          if(expandable())
          expand();
          else
          throw range_error("The array is full, but we can't expand it");
          }

          array[++lastElement] = newElement;

          The comments in English add no value at all: they simply repeat, in a more verbose and less precise fashion, what the code already says.

          I'm not really sure what you're trying to demonstrate with the assertions

          • by Raenex ( 947668 )

            Apologies for losing the indentation; how do you get Slashdot not to do that?

            Plain Old Text with <ecode> does the trick.

            It took me awhile to figure this out, as there is no obvious link to help on formatting your posts (eventually found some help [slashdot.org] via Google).

            Up until now I've been using HTML Formatted, since Plain Old Text sounded un-web like. <ecode> doesn't work very well with HTML Formatted, because it doesn't preserve the space and you can't add them with &nbsp;. Turns out Plain Old Text is what I wanted all along anyways. Just hit return twice when you want

  • 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
    • by Coryoth ( 254751 ) on Saturday March 10, 2007 @07:22AM (#18298746) Homepage Journal

      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.
      And indeed, this can be done, and is available for a number of DbC systems. Check out JML which has ESC/Java2 to provide static contract checking for Java, Spec# (C# with contracts) which uses the Spec# verifier for static checking of contracts, and Eiffel with ESpec-Verify for static checking of Eiffel contracts.

      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?
      The difference between DbC and unit tests (and really, you should be doing both) is that if a test can be expressed as a constraint then it is useful to simply express that as a contract, while if the test is a specific input to output matching test then it is going to be useful as a separate unit test. When you run your unit tests the contract constraints will automatically get checked. More importantly they will help isolate exactly where the error occured when testing integrated systems. Furthermore, by putting constraints as contracts you have improved your API documentation (any decent DbC system includes automated inclusion of contract information in API documentation) which helps other people use your code correctly, and makes maintenance easier.

      Finally contracts allow automated testing. That's where you automatically generate data to pass to the code and let the contracts act as a test oracle to catch and locate problems. With something like AutoTest for Eiffel the data generation can be purely random (constrained by preconditions of course), or designed to sample the input according to best coverage via genertic algorithms, etc. The result is that you find corner cases that you might not have anticipated with your unit tests - and you would be surprised how often that happens, AutoTest found a number of subtle bugs in Eiffel's base libraries which had been production code for years.

      When there's a DbC language or add-on that checks the contracts at compile time, I'll be interested.
      Then you really need to check out JML [iastate.edu] and ESC/Java2, and Spec# [microsoft.com], because you would be interested.
      • by Sircus ( 16869 )

        Then you really need to check out JML [iastate.edu] and ESC/Java2, and Spec# [microsoft.com], because you would be interested.
        Thanks - I'll check out JML and ESC/Java2 (we're using Java throughout, both client and server-side).
      • Re: (Score:2, Insightful)

        by Tablizer ( 95088 )
        if a test can be expressed as a constraint then it is useful to simply express that as a contract,

        Us table-heads who like to shift the processing burden to the database instead of application languages would point out that this resembles database constraints and triggers.
             
  • 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 th
    • by NovaX ( 37364 )
      Wow, that's so utterly wrong. You write contracts against methods, and thus express in the code explicitly the method's intent. This makes it easier to refactor because the code is clearer and the callers can't abuse it. You have an easier time refactoring this type of code because you know it is correct. And its easier to test after you've refactored because it won't hide bugs by spitting out wrong answers, but instead make them known. People who put the tiny amount required will have enough pride in thei
    • by Coryoth ( 254751 )

      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.

      That DbC is up front design is simply not true. You can do "Contract Driven Design" as well as you can do "Test Driven Design" (though of course combining tests and contracts, using each where they make sense - contrct for constraints, tests for explicit input to output mappings - is the best bet). Indeed there are even frameworks like ESpec [yorku.ca] which are specifically designed for doing XP in Eiffel using contracts. Try reading one of the ESpec papers on XP programming with ESpec [yorku.ca]. Think of it this way - DbC is

  • Already mostly done (Score:4, Informative)

    by Todd Knarr ( 15451 ) on Saturday March 10, 2007 @05:45AM (#18298452) Homepage

    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.

    • by Coryoth ( 254751 )

      As has been noted, most programmers already do design-by-contract, they just don't call it that. They call it argument checking.

      The argument against this is that it is confusing implementation and specification. A contract is separate from the code implementing the function, and is automatically included in the API documentation for the function. That makes it easier for other people to use the code (they don't have to have access to the source code, or bother reading through all your code, just to be able to know they are calling your code correctly and what they can expect of the result), and for you to maintain your code. There'

    • 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.
      • by Coryoth ( 254751 )
        Just because you're interested I'll do a little boosterism for the Java DbC system because it is actually pretty cool. First I'll admit the downside: it works by embedding annotations for contracts in comments (like JavaDoc comments basically) which makes it a little bit hacked on, but you take what you can get. The upsides include: good tool support, so not only do you get a compiler that converts annotations into runtime checks, but a version of JavaDoc that incorporates annotations into the auto-generate
        • Cool. Thanks for the reply and journal link. I haven't read the whole thing yet, but I'll review it for a new project I'm starting work on soon. I'm funding this one myself, and somehow that makes design by contract much more appealing. :)
    • I wonder who voted your post to five informative, as you seem to be quite uninformed on the topic. DbC isn't argument checking. As Bertrand Meyer states in his seminal "Object-Oriented Software Construction":

      Non-Redundancy principle: Under no circumstances shall the body of a routine ever test for the routine's precondition.

      This rule is the reverse of what many software engineering or programming methodology textbooks advocate, often under the name of defensive programming -- the idea that to obtain reli

      • Re: (Score:3, Insightful)

        by Todd Knarr ( 15451 )

        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 o

  • by imbaczek ( 690596 ) <(mf.atzcop) (ta) (kezcabmi)> on Saturday March 10, 2007 @06:35AM (#18298572) Journal
    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.
    • Or, better yet... (Score:5, Informative)

      by Chemisor ( 97276 ) on Saturday March 10, 2007 @10:21AM (#18299438)
      > 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.
    • by Coryoth ( 254751 )

      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 agree that asserts do the job well. I'm just trying to point out that a good DbC system, such as some of the ones mentioned in the article, provide significant tool support which makes contracts considerably better than asserts. For example, DbC systems will have compilers that understand contracts, and extended syntax designed specifically for expressing constraints such and post conditions. A simple postcondition like x > old(x) is harder to manage with assert statements - you need extra code to sav

    • A good design by contract system can and should catch a lot of these errors at compile time.

      That is the difference.

      If you only catch something at runtime with an assert it is already too late.

      Among the Haskell programming community there is a tongue-in-cheek saying, "if it compiles it is correct." This happens because the type system is so strong, it is hard to write a program that compiles, but doesn't do what it is designed to do.

      Design by contract offers similar benefits to more imperative languages.

      Thou
  • 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 c
  • Apart from "it's too hard", I think Unit Testing has overtaken DbC as an approach.

    - 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 s
  • Side Effects (Score:2, Insightful)

    by somepunk ( 720296 )
    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.
    • Like a compiler [haskell.org]? If your functions don't fit the model, change your functions, not your model. Functional programing makes errors reproducible, tractable, and fixable. And you can do it any language.
  • Most programmers aren't interested enough in technology to even know what Design By Contract is.
  • Very simple (Score:3, Insightful)

    by jilles ( 20976 ) on Saturday March 10, 2007 @11:29AM (#18299800) Homepage
    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.
    • by Coryoth ( 254751 )

      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.

      Well obviously if you're doing it post hoc it is going to be expensive, but that's a silly complaint. You should be developing contracts at the same time as you're developing code. That shouldn't be costing you much extra time because you are supposed to be writing documentation and tests for your code anyway, and contracts are as simple as writing the documentation of a function as constraints in the programming language itself (suitably extended with more expressive syntax for riting constraints) instead

      • by jilles ( 20976 )
        Well sounds nice in theory but I don't see it in practice. I'm aware of numerous very large projects with automated test suites. I'm aware of none (as in 0) very large projects with design by contract practices in place (except maybe for places like NASA which accept rediculously high cost in exchange for better quality).

        I don't know what you mean by post hoc writing of contracts. Generally the idea of a contract is that you write the contract first and then the code. Generally the contract writing bit is a
    • 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.

      By a similar argument, we should all give up with unit and integration testing, because the additional effort required to write automated tests for individual modules and then for interactions between t

  • 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
  • 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.

    • Most projects are RAD, and as such, there's no time/room/whatever for DbC.

      Most software projects also produce crap at the end. As with much in life, you get what you pay for.

  • 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 th
    • > So the short answer is, DbC is extremely common, but it can't be called that by anyone
      > but Bertrand Meyer and his licensees.

      It can be called that by anyone who is not using it as a label to sell something.
  • 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

"It's a dog-eat-dog world out there, and I'm wearing Milkbone underware." -- Norm, from _Cheers_

Working...