[Python-ideas] Why is design-by-contracts not widely adopted?

Steven D'Aprano steve at pearwood.info
Sat Sep 29 04:20:10 EDT 2018


On Tue, Sep 25, 2018 at 08:01:28PM +1200, Robert Collins wrote:
> On Mon, 24 Sep 2018 at 19:47, Marko Ristin-Kaufmann
> <marko.ristin at gmail.com> wrote:
[...]
> > There are 150K projects on pypi.org. Each one of them would 
> > benefit if annotated with the contracts.
> 
> You'll lose folks attention very quickly when you try to tell folk
> what they do and don't understand.
> 
> Claiming that DbC annotations will improve the documentation of every
> single library on PyPI is an extraordinary claim, and such claims
> require extraordinary proof.

This is not a scientific paper, or an edited book. Its an email forum, 
and communication is not always as precise as it could be. We should 
read such statements charitably, not literally and pedantically.

But having said that... would it be an "extraordinary claim" to state 
that all 150K projects on PyPI would benefit with better documentation, 
tests or error checking? I don't think so.

I think it would be extraordinary to claim that there was even a single 
project that *wouldn't* benefit from at least one such patch. I'd like 
to see this glorious example of software perfection, and bow down in awe 
to its author.

Contracts combine error checking, documentation and testing all in one. 
Ergo, if a project would benefit from any of those things, it would 
benefit from a contract.

Anticipating an objection: like tests and documentation and error 
checking, contracts do not need to be "all or nothing". A contract can 
be incomplete and still provide benefit. We can add contracts 
incrementally. Even a single pre- or post-condition check is better than 
no check at all.

So I'm with Marko here: every project on PyPI would, in principle, 
benefit from some contracts. I say in principle only because in 
practice, the available APIs for adding contracts to Python code are so 
clunky that the cost of contracts are excessive. We're paying a syntax 
tax on contracts which blows the cost all out of proportion.

Just as languages like Java pay a syntax tax on static typing (compared 
to languages like ML and Haskell with type inference and few 
declarations needed), and languages like COBOL have a syntax tax on, 
well, everything.


> I can think of many libraries where necessary pre and post conditions
> (such as 'self is still locked') are going to be noisy, and at risk of
> reducing comprehension if the DbC checks are used to enhance/extended
> documentation.

So long as my editor lets me collapse the contract blocks, I don't need 
to read them unless I want to. And automatically generated documentation 
always tends towards the verbose. Just look at the output of help() in 
the Python REPL. We learn to skim, and dig deeper only when needed.


> Some of the examples you've been giving would be better expressed with
> a more capable type system in my view (e.g. Rust's), but I have no
> good idea about adding that into Python  :/.

Indeed.

A lot of things which could be preconditions in Python would be 
type-checks in Eiffel. With gradual typing and type annotations, we 
could move some pre-condition and post-condition checks into the type 
checker.

(Static typing is another thing which doesn't need to be "all or 
nothing".)


> Anyhow, the thing I value most about python is its pithyness: its
> extremely compact, allowing great developer efficiency,

None of that changes. The beauty of contracts is that you can have as 
many or as few as make sense for each specific class or function, or for 
that matter each project. If your project is sufficiently lightweight 
and the cost of bugs is small enough, you might not bother with tests or 
error checking, or contracts.


-- 
Steve


More information about the Python-ideas mailing list