Hi Robert,

You'll lose folks attention very quickly when you try to tell folk
what they do and don't understand.

I apologize if I sounded offending, that was definitely not my intention. I appreciate that you addressed that.

I suppose it's cultural/language issue and the wording was probably inappropriate. Please let me clarify what I meant: there was a  misconception as DbC was reduced to a tool for testing, and, in a separate message, reduced to type-checks at runtime. These are clearly misconceptions, as DbC (as origianally proposed by Hoare and later popularized by Meyer) include other relevant aspects which are essential and hence can not be overseen or simply ignored. If we are arguing about DbC without these aspects then we are simply falling pray to a straw-man fallacy.

Claiming that DbC annotations will improve the documentation of every
single library on PyPI is an extraordinary claim, and such claims
require extraordinary proof.

I don't know what you mean by "extraordinary" claim and "extraordinary" proof, respectively. I tried to show that DbC is a great tool and far superior to any other tools currently used to document contracts in a library, please see my message https://groups.google.com/d/msg/python-ideas/dmXz_7LH4GI/5A9jbpQ8CAAJ. Let me re-use the enumeration I used in the message and give you a short summary.

The implicit or explicit contracts are there willy-nilly. When you use a module, either you need to figure them out using trial-and-error or looking at the implementation (4), looking at the test cases and hoping that they generalize (5), write them as doctests (3) or write them in docstrings as human text (2); or you write them formally as explicit contracts (1).

I could not identify any other methods that can help you with expectations when you call a function or use a class (apart from formal methods and proofs, which I omitted as they seem too esoteric for the current discussion).

Given that:
* There is no other method for representing contracts,
* people are trained and can read formal statements and
* there is tooling available to write, maintain and represent contracts in a nice way

I see formal contracts (1) as a superior tool. The deficiencies of other approaches are:
2) Comments and docstrings inevitably rot and get disconnected from the implementation in my and many other people's experience and studies.
3) Doctests are much longer and hence more tedious to read and maintain, they need extra text to signal the intent (is it a simple test or an example how boundary conditions are handled or ...). In any non-trivial case, they need to include even the contract itself.
4) Looking at other people's code to figure out the contracts is tedious and usually difficult for any non-trivial function.
5) Test cases can be difficult to read since they include much broader testing logic (mocking, set up). Most libraries do not ship with the test code. Identifying test cases which demonstrate the contracts can be difficult.

Any function that is used by multiple developers which operates on the restricted range of input values and gives out structured output values benefits from contracts (1) since the user of the function needs to figure them out to properly call the function and handle its results correctly. I assume that every package on pypi is published to be used by wider audience, and not the developer herself. Hence every package on pypi would benefit from formal contracts.

Some predicates are hard to formulate, and we will never be able to formally write down all the contracts. But that doesn't imply for me to not use contracts at all (analogously, some functionality is untestable, but that doesn't mean that we don't test what we can).

I would be very grateful if you could point me where this exposition is wrong (maybe referring to my original message, https://groups.google.com/d/msg/python-ideas/dmXz_7LH4GI/5A9jbpQ8CAAJ, which I spent more thought on formulating).

So far, I was not confronted against nor read on the internet a plausible argument against formal contracts (the only two exceptions being lack of tools and less-skilled programmers have a hard time reading formal statements as soon as they include boolean logic and quantifiers). I'm actively working on the former, and hope that the latter would improve with time as education in computer sciences improves.

Another argument, which I did read often on internet, but don't really count is that quality software is not a priority and most projects hence dispense of documentation or testing. This should, hopefully, not apply to public pypi packages and is highly impractical for any medium-size project with multiple developers (and very costly in the long run).

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.

It is up to the developer to decide which contracts are enforced during testing, production or displayed in the documentation (you can pick the subset of the three, it's not an exclusion). This feature ("enabled" argument to a contract) has been already implemented in the icontract library.
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  :/.
I don't see how type system would help regardless how strict it would be? Unless each input and each output represent a special type, which would be super confusing as soon as you would put them in the containers and have to struggle with invariance, contravariance and covariance. Please see https://github.com/rust-lang/rfcs/issues/1077 for a discussion about introducing DbC to Rust. Unfortunately, the discussion about contracts in Rust is also based on misconceptions (e.g., see https://github.com/rust-lang/rfcs/issues/1077#issuecomment-94582917) -- there seems to be something wrong in the way anybody proposing DbC exposes contracts to the wider audience and miss to address these issues in a good way. So most people just react instinctively with "80% already covered with type systems" / "mere runtime type checks, use assert" and "that's only an extension to testing, so why bother" :(.

I would now like to answer Hugh and withdraw from the discussion pro/contra formal contracts unless there is a rational, logical argument disputing the DbC in its entirety (not in one of its specific aspects or as a misconception/straw-man). A lot has been already said, many articles have been written (I linked some of the pages which I thought were short & good reads and I would gladly supply more reading material). I doubt I can find a better way to contribute to the discussion.

Cheers,
Marko
 

On Tue, 25 Sep 2018 at 10:01, Robert Collins <robertc@robertcollins.net> wrote:
On Mon, 24 Sep 2018 at 19:47, Marko Ristin-Kaufmann
<marko.ristin@gmail.com> wrote:
>
> Hi,
>
> Thank you for your replies, Hugh and David! Please let me address the points in serial.
>
> Obvious benefits
> You both seem to misconceive the contracts. The goal of the design-by-contract is not reduced to testing the correctness of the code, as I reiterated already a couple of times in the previous thread. The contracts document formally what the caller and the callee expect and need to satisfy when using a method, a function or a class. This is meant for a module that is used by multiple people which are not necessarily familiar with the code. They are not a niche. 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.

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.

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  :/.

Anyhow, the thing I value most about python is its pithyness: its
extremely compact, allowing great developer efficiency, but the cost
of testing is indeed excessive if the tests are not structured well.
That said, its possible to run test suites with 10's of thousands of
tests in only a few seconds, so there's plenty of headroom for most
projects.

-Rob