Adding Optional Static Typing to Python

Link: Guido van Rossum broaches the subject of type tagging for Python.

Optional static typing has long been requested as a Python feature. It's been studied in depth before (e.g. on the type-sig) but has proven too hard for even a PEP to appear. In this post I'm putting together my latest thoughts on some issues, without necessarily hoping to solve all problems.

Static vs. dynamic is a never-ending thread in most PL discussions these days. But designing a type system is a *hard* task, one which I'm not sure doesn't require from a ground on up approach. But it would be nice if you could choose to work your way into, though most of the Smalltalk crowd will inform us that Strongtalk never did quite catch on.


(accompanying discussion forum)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I don't like what I see

I wonder why nobody is suggesting to use a type system like the lispish ones.
And am I wrong or VisualWorks has some kind of "protocol" declarations?

This seem reasonable approach for a dynamic language (and I don't think we can make python haskell-like).

I'm afraid that GvR is being left in the hands of the static guys ;)

the first thing i looked for

the first thing i looked for was how he would handle mixed lists. it doesn't seem to be addressed. has anyone done any work on inferring types for (or otherwise handling) mixed lists? obviously it's a can of worms that can't be solved in the completely general case, but how far has anyone got?

Base classes?

Most static OO languages require the list to be of some base class that determines the list type. Existential types in functional languages serve a similar purpose. Of course, you're left with a bunch of upcasting and downcasting.

HLists

See HLists, a way of having heterogeneous linked lists in Haskell. I'm not sure if this is what you want, though I don't see how this can be done without just knowing the type of each element. http://homepages.cwi.nl/~ralf/HList/

thanks - interesting paper.

thanks - interesting paper. in more general terms, i think i need to look at dependent types (which, i think, are the basis for the paper, though i've only skimmed it so far).

mixed lists

You might want to have a look at Merd, a largely incomplete, dynamic functional language with some interesting features. In Merd, as I understand it, lists contain a union of types.

http://merd.sourceforge.net/

Relevant excerpt from Merd web site:

# Try hard to keep the more precise types
  [ 1, "foo" ] !! [ 1 | "foo" ]
means the type of list [ 1, "foo" ] is a list of elements of type 1|"foo"

# existential-like types with subtyping:
  [x,y] !! [Int|String] with x !! Int ; y !! String
means type of list [x,y] is a list of elements of type Int|String

  [ 1, "foo" ].map(+ 1) is ill-typed, but
  [ 1, "foo" ].map(+ 1|&|"bar") gives [ 2, "foobar" ] 


python and static typing

If it wont increase the effeciency of execution, there is really no point in having it. Using static typing to ensure code reliability is silly in a language with side affects, particularly one that lets you dynamically alter classes at run-time. The slightest change of state can effectively nullify the benefits of static typing. All static typing will do in python is decrease the flexibility of the syntax.

I have some ideas for a system that will help augment reliability without diminishing flexibility. It encompasses run-time type checking, but it does quite a bit more - it utilizes predicate based argument constraints.

I wrote a blog post at libervis about it, and a few ideas I had regarding DBC syntax in python.

Couple of questions

I agree that a DbC point of view is probably a better way to go with Python. WRT to your suggestions, most of the examples of predicates have to do with class level properties. Can you have predicates that test method parameters?

One thing that strikes me is that you are trying to have Named Assertions. But this simply redirects the question to why we would believe that assertions() as provided by Python are insufficient as a DbC mechanism (not to mention whether this is really a Unit Test problem). Well, I suppose the Eiffel folks would argue that there is no formal mechanism for documenting the assertions as part of the class/method/property signature. I guess you could also hold that there's no mechanism for automatically enforcing the classs level invariants.

Anyhow, if documentation is the aim, I think you need to have the predicates as a formal part of the declaration syntax, lest it's impossible to discern what's a pre, post, or invariant.

named assertions

You make some good points, there are a few things that I should flesh out to increase the clarity of my ideas.

The point of named assertions is reusability -

compare this:

pred Iterable:
  hasattr(self, "__iter__")

def map(fn, lst:Iterable):
  # ...

def filter(fn, lst:Iterable):
  # ...

with something like:

def map(fn, lst):
  ?:
    hasattr(lst, "__iter__")
  # ...

def filter(fn, lst):
  ?:
    hasattr(lst, "__iter__")
  # ...

In the long run, you can increase the modularity and reusability of your conditions if you define them as self-standing predicates.

You can easily have predicates that test method parameters, but if your conditions are specific to a single method, it makes more sense to put them in the method conditional block rather than in an external predicate. One should only define an external predicate if one intends on using the same conditions in multiple places.

An example of a predicate that tests a method parameter:

pred negative:
  self 

Part II

Guido gives more detail on Adding Optional Static Typing to Python -- Part II. Probably deserves to be elevated to the front page (but I'm buried in ml at the moment).