[Python-ideas] Simplicity of C (was why is design-by-contracts not widely)

Chris Angelico rosuav at gmail.com
Sun Sep 30 00:50:28 EDT 2018

On Sun, Sep 30, 2018 at 2:27 PM Steven D'Aprano <steve at pearwood.info> wrote:
> On Sun, Sep 30, 2018 at 12:17:25PM +1000, Chris Angelico wrote:
> > On Sun, Sep 30, 2018 at 11:54 AM Steven D'Aprano <steve at pearwood.info> wrote:
> > > This discussion is for those of us who would like to include DbC in our
> > > projects but don't like existing solutions. C++ being designed with a
> > > shovel is not relevant.
> > >
> > > (Except in the sense that we should always be careful about piling on
> > > feature upon feature into Python.)
> >
> > And as such, I do not want to see dedicated syntax for no purpose
> > other than contracts.
> That's a reasonable objection, except that contracts are a BIG purpose.

I think that's a matter of debate, but sure, let's accept that
contracts are big.

> Would you object to dedicated syntax for object oriented programming?
> (Classes and methods.) I hope not. Imagine if OOP in Python was limited
> to an API like this:

TBH I don't think contracts are nearly as big a tool as classes are.

> MyClass = type(name="MyClass", parent=object)
> MyClass.add_method(__init__=lambda self, arg: setattr(self, "arg", arg))
> MyClass.add_method(__str__=lambda self: "MyClass(%r)" % (self.arg,))
> MyClass.add_method(spam=lambda self, x, y: (self.arg + x)/y)
> MyClass.add_method(eggs=lambda self, x, y: self.arg*x - y)
> MyClass.add_member(cheese='Cheddar')
> MyClass.add_member(aardvark=None)

Actually, that's not far from the way JavaScript's class hierarchy
was, up until ES2015. Which suggests that a class keyword is a
convenience, but not actually essential.

> I know that adding syntax is a big step, and should be considered a last
> resort for when a library or even a built-in won't work. But adding
> contracts isn't a small benefit. Its not a magic bullet, nobody says
> that, but I would say that contracts as a feature is *much* bigger and
> more important than (say) docstrings, and we have dedicated syntax for
> docstrings.

Hmm, what we really have is just string literals, plus a bit of magic
that says "if the first thing in a function/class is a string literal,
we save it". But sure.

> > What I'm interested in is (a) whether something
> > can and should be added to the stdlib, and (b) whether some specific
> > (and probably small) aspect of it could benefit from language support.
> > As a parallel example, consider type hints. The language has ZERO
> > support for special syntax for a language of types.
> That's a weird use of the word "ZERO" :-)
>     def spam(x: int) -> float:
>         y: int
> I count three special syntax forms for a language of types:
> - parameter type hints;
> - return type hints;
> - variable type hints.
> (Yes, I'm aware that *technically* we can put anything we like in the
> hints, they don't have to be used as type hints, but Guido has made it
> clear that such uses are definitely of second-rate importance and only
> grudgingly supported.)

That's exactly my point though. The syntax is for "attach this thing
to that function". There is no syntax for a language of types, a type
algebra syntax. We don't have a syntax that says "tuple containing
int, two strings, and float". The syntactic support is the very
smallest it can be - and, as you say, it's not actually restricted to
type hints at all. If I'm reading the dates correctly, annotations
were completely non-specific from 2006 (PEP 3107) until 2014 (PEP

So what is the smallest piece of syntactic support that would enable
decent DbC? And "none at all" is a valid response, although I think in
this case it's incorrect.

> > What you have is
> > simple, straight-forward names like "List", and the normal behaviours
> > that we already can do such as subscripting. There is language
> > support, however, for attaching expressions to functions and their
> > arguments.
> Your point is taken that there is no separate syntax for referring to
> the types *themselves*, but then there's no need for such. int is int,
> whether you refer to the class "int" or the static type "int".

The static type "int" is one of the simplest possible type
declarations. There are much more complicated options.

> > At the moment, I'm seeing decorator-based contracts as a clunky
> > version of unit tests.
> Contracts are not unit tests.
> Contracts and unit tests are complementary, and overlap somewhat, but
> they are the same. Unit tests only test the canned values you write in
> you tests. Contracts test real data you pass to your application.

And yet all the examples I've seen have just been poor substitutes for
unit tests. Can we get some examples that actually do a better job of
selling contracts?


More information about the Python-ideas mailing list