[Types-sig] RFC 0.1

Tim Peters tim_one@email.msn.com
Wed, 15 Dec 1999 05:32:20 -0500


[Greg Stein]
> Note that one benefit of associating types with names, is that
> you can shortcut the data flow analysis (so the analysis is not
> necessarily the same). But: you cannot have a name refer to
> different types of objects (which I don't like; it reduces some
> of Python's polymorphic and dynamic behavior (interfaces solve
> the polymorphism stuff in a typed world)).

[Guido]
> This is a bogus argument.  From the point of view of human
> readability, I find this:
>
>    s = "the quick brown fox"
>    s = string.split(s)
>    del s[1]			# the fox is getting old
>    s = string.join(s)
>
> less readable and more confusing than this:
>
>    s = "the quick brown fox"
>    w = string.split(s)
>    del w[1]			# the fox is getting old
>    s = string.join(w)
>
> The first version gives polymorphism a bad name; it's like a sloppy
> physicist using the same symbol for velocity and accelleration.

It's an excellent example, but to me the *first* is easier to follow!  In
the 2nd I'm left wondering what further use will be made of w, so have to
try to keep w *and* s alive in my short-term memory.  In the 1st, I can
scrub my brain cleaner harder oftener.

Heck, I wrote this just last week -- and deliberately:

        result = {}
        for i in xrange(k):
            # The expected # of times thru the next loop is n/(n-i).
            # Since i < k <= n/2, n-i > n/2, so n/(n-i) < 2 and is
            # usually closer to 1:  on average, this succeeds very
            # quickly!
            while 1:
                candidate = int(random() * n)
                if not result.has_key(candidate):
                    result[candidate] = 1
                    break
        result = result.keys()
        result.sort()
        return result

At the start of its life, the result is a (conceptual) set, and at the end
it's a list with the same stuff.  That's not confusing -- it's helpful!  It
wouldn't confuse a decent type-inference engine, either ("result" is a dict
until the block starting with the .keys() call, and is a list thereafter;
it's not even a "union type" -- at any given point, it's always one or the
other).

> ...
> Note that a type inferencer may not be able to deduce the rules I
> stated above, since you could construct an example where there is no
> single type <something> and yet the whole thing works.  E.g. I could
> create a list [1, 2, 3, joint, "a", "b", "c"] where joint is an
> instance of a class that when added to an int returns a string.

Now *that's* what gives polymorphism a bad name <0.9 wink>.

> However if we had a typesystem and notation that couldn't express
> this easily but that could express the stricter rules, I bet that
> no-one would mind adding the stricter type declarations to the
> code, since those rules most likely express the programmer's intent
> better.

I agree there's little payback in making a type system that can represent
everything possible, simply because 99% of the benefit is in capturing
vanilla types (which certainly includes lists of X and dicts mapping X to Y
and functions taking lists of X returning dicts mapping Y to lists of Z
...).

shocked-at-what-some-people-find-unreadable-ly y'rs  - tim