Type Hinting vs Type Checking and Preconditions

Paul Boddie paul at boddie.org.uk
Wed Mar 8 02:10:14 CET 2006

Roy Smith wrote:
> In article <1141764243.936880.324240 at i39g2000cwa.googlegroups.com>,
>  "Tom Bradford" <bradford653 at gmail.com> wrote:
> >
> > def multiplyByTwo(value):
> >     return value * 2


> The question is, what is the function *supposed to do*?  Without knowing
> what it is *supposed to do*, it is impossible to say for sure whether
> returning "1414" is correct or not.

Indeed. And I don't think arithmetic-based examples are really very
good at bringing out the supposed benefits of type declarations or are
very illustrative when reasoning about type systems, mostly because
everyone assumes the behaviour of the various operators without
considering that in general the behaviour is arbitrary. In other words,
people look at expressions like "a * b" and say "oh yes, numbers being
multiplied together producing more numbers" without thinking that "a"
might be an instance of "Snake" and "b" might be an instance of
"Reptile" and the "Snake.__mul__" method (or perhaps the
"Reptile.__rmul__" method) might produce a range of different things
that aren't trivially deduced.

>  Consider two different functions:
> def multiplyByTwo_v1(value):
>     """Returns the argument multiplied by 2.  If the argument is a
>        string representation of an integer, another string is returned
>        which is the string representation of that integer multiplied
>        by 2.
>     """"
>     return value * 2
> def multiplyByTwo_v2(value):
>     """Returns the argument multiplied by 2.
>     """"
>     return value * 2
> The first one should return "28" when passed "14".  If it returns "1414",
> it's broken.  I know this seems rather silly and pedantic, but it's an
> important point.

I've done some work on this kind of thing which actually specialises
functions/methods and produces something resembling that quoted above,
and I believe that various other works produce similar specialisations
when reasoning about the behaviour of Python programs. Specifically,
you'd write the first version like this:

def multiplyByTwo_v1(value):
    if isinstance(value, int): return int.__mul__(value, 2)
    elif isinstance(value, string): return string.__mul__(value, 2)
    else: raise RuntimeError

Really, you'd want to avoid having a single specialisation, having
separate ones for each "incoming type", although that might be hard to
arrange in every case.


P.S. Have a look here for some simple (and now quite dated) examples:


Specifically, here:

(A good test of CSS standards compliance if nothing else!)

I'll hopefully make a new release at some point in the near future
which tries to do a better job at deducing the various types and
invocation targets.

More information about the Python-list mailing list