optional static typing guido van rossum (with paul prescod, greg stein, and the types-sig)

17
Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Upload: ethan-evans

Post on 27-Mar-2015

213 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Optional Static Typing

Guido van Rossum(with Paul Prescod, Greg Stein,

and the types-SIG)

Page 2: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Talk Overview

• Why add static type checking?• Checked vs. unchecked modules• Declaration syntax• Type expressions• Dynamic casts• Parameterized types• Open issues• Implementation...?

Page 3: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Why Add Static Typing?

• Two separate goals:– faster code (OPT)– better compile-time errors (ERR)

• Mostly interested in (ERR)– (OPT) will follow suit

• Of course it will be optional– and (mostly) backwards compatible

Page 4: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Checked vs. Unchecked

• A module is checked or unchecked– no partially checked modules

• Checked modules are:– guaranteed not to raise runtime type errors

• except at point of call from unchecked modules• except at explicit dynamic casts

– protected at runtime against violations by unchecked modules

• e.g. messing with __dict__ or assignment to module globals or class/instance variables

Page 5: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Declaration Syntax

• Two forms: inline and explicit– explicit form is easy to remove

• Inline:• def gcd(a: int, b: int) -> int: ...

• Explicit (two variants):• decl gcd: def(int, int) -> int

def gcd(a, b): ...• def gcd(a, b):

decl a: int, b: int decl return: int ...

Page 6: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Declaring Classes

• decl in class declares instance attributes– (by default, anyway)– can add syntax for private, protected etc.– methods declared excluding ‘self’

• derived classes must play by the rules– can’t override methods w. conflicting types– must call Base.__init__()– once this exists, we can think about

require/ensures again!

Page 7: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Type Expressions

• standard types (in __builtin__):– int, long, float, complex, str, tuple, list, dict

• int is same as types.IntType, etc.

– None (special case: type == value)

• standard abstract types (__builtin__):– number, string, sequence, mapping, any

• class names:– may be imported from checked modules

• typedefs (decl myType = P.M.Type)

Page 8: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Constructing Types

• Syntax for type composition:– list with items of type T: [T]– tuple of T1, T2, T3: (T1, T2, T3)

• (this explains why we have both tuples and lists!)

– dict with key/value types T1/T2: {T1: T2}– union of types T1 and T2: T1 | T2– function (e.g.): def(T1, T2)->T3

• Example:– {str: (int, int) | (int, int, str) | None}

Page 9: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Dynamic Casts

• Proposed by Greg Stein• General syntax: expression ! type• Example: x = y ! int

– if y has type int: assign y to x– otherwise: raise TypeError

• Problem:– must catch exception to decide union type

• Alternative: ‘typecase’ statement?– no syntax proposal exists yet

Page 10: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Parameterized Types

• Needed e.g. for container classes:class Stack<T>:

decl st: Tdef __init__(self): self.st = []def push(self, x: T): self.st.append(x)def pop(self) -> T: x = self.st[-1]; del self.st[-1]; return x

decl IntStack = Stack<int> # template instantiationdecl s: IntStacks = IntStack() # or s = Stack() ???s.push(1)decl x: intx = s.pop()s.push("spam") # ERROR

Page 11: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Parameterized Functions

• Example:def bisect<T>(a: [T], x: T) -> int:

decl lo, mid, hi: intlo, hi = 0, len(a)while lo < hi: mid = (lo+hi)/2 if x < a[mid]: hi = mid else: lo = mid+1return lo

decl a: [int]

• Idea:– bisect() could be called without template instantiation– argument types will be matched against the type parameters <T>

Page 12: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Open Issues (1)

• A subclass is not always a subtype!• int is a subtype of any, but [int] not of [any]• similar for parameterized classes

• Dynamic cast or typecase statement?• Should we declare exceptions? How?• How much type inference is needed?• Interface declarations?• var=default:type -or- var:type=default?

Page 13: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Open Issues (2)

• Access to type objects at runtime– reflection on types must be possible

• How to spell arbitrary tuple of T: (T*)?• Typedef syntax (in expressions?)• Type conformance rules• Syntax ambiguity for lambda• How to spell the type of self• Should classes be types? (Yes!)

Page 14: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Open Issues (3)

• Avoid NameError and AttributeError?– Need flow analysis plus special rules

• e.g. all instance variables must be defined when __init__ returns (but what about calls it makes?)

• for local variables, it’s relatively easy• for globals, how to do it?• how to deal with recursive imports? blah!

• Choice of names– int/integer, str/string may be too confusing

Page 15: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Implementation...?

• Who? me? :-)• Possible phases:

– Experimental type checker written in Python• can hide decl from Python in string literals

– Allow alternate parsers in core Python• checked modules could use *.cpy extension

– Support for type checker in bytecode– Rewrite checker in C as part of core Python– Add aggressive optimizer

Page 16: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Typecase Strawman

decl x: int | string | None | [any] | ....

typecase x:int, i: print “an int: %d” % istring, s: print “a string: %s” % `s`None: print “nothing”else: print “don’t know”

• All possible types must be accounted for, otherwise it’s a static error

Page 17: Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)

Contravariance

class B:def method(self, x: number) -> int|long: ...def other(self): decl i: int|long i = self.method(3.14)

class D(B): def method(self, x: int) -> int|long: ... # ERRORclass D’(B):

def method(self, x: any) -> int: ... # okclass D’’(B):

def method(self, x: number) -> any: ... # ERROR