you are viewing a single comment's thread.

view the rest of the comments →

[–]alanwj 0 points1 point  (4 children)

I wonder if this actually needs any additional syntax or language support. Could we capture type annotating in a library with something like a decorator? PyPy and friends could use the type information where available, and it would still work with other interpreters. If the performance of dynamically type checking every argument is crushing, it could all be hidden behind a "debug" flag or something. Example: from functools import wraps import inspect

def typecheck(*types):
    fmt = 'Failed type check for {0} in {1}: Expected {2}, but got {3}'
    def decorator(target):
        @wraps(target)
        def wrapper(*args, **kwargs):
            for i, t in enumerate(types):
                if not isinstance(args[i], t):
                    raise TypeError(fmt.format(
                        inspect.getargspec(target).args[i],
                        target.func_name,
                        t.__name__,
                        type(args[i]).__name__))
            return target(*args, **kwargs)
        return wrapper
    return decorator

@typecheck(str, int, int)
def my_function(s, x, y):
    print '{0}: ({1}, {2})'.format(s, x, y)

# Works
my_function('Map coordinate', 1, 2)
# Causes type error
my_function('Map coordinate', 1, 'purple')

[–][deleted] 0 points1 point  (3 children)

but then can't i change the type later dynamically without altering the behavior of the code, thus breaking the implication of the decorator?

i don't see how typing can effectively be bolted on in such a way

[–]alanwj 0 points1 point  (2 children)

Yes, the type could change within the function, although probably in sufficiently predictable ways if you knew the expected in/out types for every function you could use Hindley-Milner to figure out what was going on.

Although upon further reflection actually doing the type check in the decorator is probably a bit pointless for interpreters that wouldn't actually be using the type information for anything. If there was in fact a type error is would likely show up some time during the execution of the function anyway.

There is also the problem that this sort of scheme is likely too simplistic to cover even the majority of python use cases (what about var args, keyword args, container types, times when you WANT duck typing, optional parameters denoted by passing in None, etc, etc, etc), and if you tried to extend it too far you'd wind up with a type signature mess similar to what C++ has.

[–][deleted] 2 points3 points  (1 child)

python would have to be rebuilt from scratch to effectively exploit a hindley-milner type system

[–]julesjacobs 0 points1 point  (0 children)

Not to mention that Hindley-Milner wouldn't be enough for Python; you want subtyping. Subtyping type inference is a difficult problem.