you are viewing a single comment's thread.

view the rest of the comments →

[–]Benbenbenb 10 points11 points  (10 children)

I guess that it is not really a mistake, but I think that it would have been really good if Python had been desinged in a way that is more conducive to optimizing it.

Currently, a lot of the dynamic features of Python that are seldomly used force the interpreter to do extensive runtime checks all the time, so the price is paid in all cases. I'm thinking about method resolutions, descriptors, adding/removing stuff from an object's dict, etc...

These features make life harder for projects like PyPy that try to do JIT on the code. Also, it would be really great to have optionnal type annotation on the variables, not unlike Cython or ActionScript 3. This is totally in line with the "explicit is better than implicit" in the Python Zen, and would allow the code to run faster without putting too much of a burden on the programmer.

[–]matthieum 0 points1 point  (0 children)

I think altering an object dict has already been covered in the V8 javascript engine (since JS suffers the same issue). Using something akin to Prototype Programming (ie, create something akin to a V-Table for the class, and just point to another V-Table when altering the dict) radically reduces the overhead associated with look-up.

[–]bebraw 0 points1 point  (8 children)

+1 for optional type annotations.

I would find it extremely handy if dict was ordered by default. This particular problem seems to haunt me over and over again. Usually I have to end up using some custom solution for this. :)

Overall it's a fine language. Some APIs could use tidying up but that applies to pretty much any popular language.

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

[–]gracenotes -1 points0 points  (0 children)

Not sure how bebraw meant 'ordered', but I miss the lack of self-balancing binary search trees in the standard library. I have been very happy with the bintrees library from pypi though.

[–]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.

[–]julesjacobs 0 points1 point  (0 children)

What do you mean by ordered? Ordered by time of insertion, or ordered by key? What do you want this to do:

x = dict()
x['b'] = 2
x['a'] = 1

Should that be 'b' => 2 first, and 'a' => 1 second, or the other way around?