[Python-ideas] Why is design-by-contracts not widely adopted?
steve at pearwood.info
Mon Oct 8 08:11:08 EDT 2018
On Mon, Oct 08, 2018 at 09:32:23PM +1100, Chris Angelico wrote:
> On Mon, Oct 8, 2018 at 9:26 PM Steven D'Aprano <steve at pearwood.info> wrote:
> > > In other words, you change the *public interface* of your functions
> > > all the time? How do you not have massive breakage all the time?
> > I can't comment about Marko's actual use-case, but *in general*
> > contracts are aimed at application *internal* interfaces, not so much
> > library *public* interfaces.
> Yet we keep having use-cases shown to us involving one person with one
> module, and another person with another module, and the interaction
> between the two.
Do we? I haven't noticed anything that matches that description,
although I admit I haven't read every single post in these threads
But "application" != "one module" or "one developer". I fail to see the
contradiction. An application can be split over dozens of modules,
written by teams of developers. Whether one or a dozen modules, it still
has no public interface that third-party code can call. It is *all*
Obviously if you are using contracts in public library code, the way
you will manage them is different from the way you would manage them if
you are using them for private or internal code.
That's no different from (say) docstrings and doctests: there are
implied stability promises for those in *some* functions (the public
ones) but not *other* functions (the private ones).
Of course some devs don't believe in stability promises, and treat all
APIs as unstable. So what? That has nothing to do with contracts. People
can "move fast and break everything" in any programming style they like.
> Which way is it? Do the contracts change frequently or not?
They change as frequently as you, the developer writing them, chooses to
change them. Just like your tests, your type annotations, your doc
strings, and every other part of your code.
> Are they public or not?
That's up to you.
Contracts were originally designed for application development, where
the concept of "public" versus "private" is meaningless. The philosophy
of DbC is always going to be biased towards that mind-set.
Nevertheless, people can choose to use them for library code where there
is a meaningful distinction. If they do so, then how they choose to
manage the contracts is up to them.
If you want to make a contract a public part of the interface, then you
can (but that would rule out disabling that specific contract, at least
If you only want to use it for internal interfaces, you can do that too.
If you want to mix and match and make some contracts internal and some
public, there is no DbC Police to tell you that you can't.
> How are we supposed to understand the point of contracts
You could start by reading the explanations given on the Eiffel page,
which I've linked to about a bazillion times. Then you could read about
another bazillion blog posts and discussions that describe it (some pro,
some con, some mixed). And you can read the Wikipedia page that shows
how DbC is supported natively by at least 17 languages (not just Eiffel)
and via libraries in at least 15 others. Not just new experimental
languages, but old, established and conservative languages like Java, C
There are heaps of discussions on DbC on Stackoverflow:
and a good page on wiki.c2:
TIL: Pre- and postconditions were first supported natively Barbara
Liskov's CLU in the 1970s.
This is not some "weird bizarre Eiffel thing", as people seem to
believe. If it hasn't quite gone mainstream, it is surely at least as
common as functional programming style. It has been around for over
forty years in one way or another, not four weeks, and is a standard,
well-established if minority programming style and development process.
Of course it is always valid to debate the pros and cons of DbC versus
other development paradigms, but questioning the very basis of DbC as
people here keep doing is as ludicrous and annoying as questioning the
basis of OOP or FP or TDD would be.
Just as functional programming is a paradigm that says (among other
things) "no side effects", "no global variables holding state" etc, and
we can choose to apply that paradigm even in non-FP languages, so DbC is
in part a paradigm that tells you how to design the internals of your
We can apply the same design concepts to any code we want, even if we're
not buying into the whole Contract metaphor:
- pre-conditions can be considered argument validation;
- post-conditions can be considered a kind of test;
- class invariants can be considered a kind of defensive assertion.
> if the use-cases being shown all involve bad code
> and/or bad coding practices?
How do you draw that conclusion?
> Contracts, apparently, allow people to violate versioning expectations
> and feel good about it.
> (Am I really exaggerating all that much here?)
"Exaggerating" is not the word I would choose to use. "Talking utter
bollocks" is probably more accurate *grin*
More information about the Python-ideas