Hi everyone,

I think we should reject, or at least postpone PEP 526.

PEP 526 represents a major change to the language, however there are, I believe, a number of technical flaws with the PEP.

It is probable that with significant revisions it can be a worthwhile addition to the language, but that cannot happen in time for 3.6 beta 1 (in 11 days).

PEP 526 claims to be an extension of PEP 484, but I don't think that is entirely correct. PEP 484 was primarily about defining the semantics of pre-existing syntax. PEP 526 is about adding new syntax. Historically the bar for adding new syntax has been set very high. I don't think that PEP 526, in its current form, reaches that bar.

Below is a list of the issues I have with the PEP as it stands.

In many cases it makes it more effort than type comments
========================================================

Type hints should be as easy to use as possible, and that means pushing as much work as possible onto the checker, and not burdening the programmer.

Attaching type hints to variables, rather than expressions, reduces the potential for inference. This makes it harder for programmer, but easier for the checker, which is the wrong way around.

For example,, given a function:
def spam(x: Optional[List[int]])->None: ...

With type comments, this is intuitively correct and should type check:
def eggs(cond:bool):
    if cond:
        x = None
    else:
        x = [] # type: List[int]
    spam(x)  # Here we can infer the type of x

With PEP 526 we loose the ability to infer types.
def eggs(cond:bool):
    if cond:
        x = None # Not legal due to type declaration below
    else:
       x: List[int] = []
    spam(x)

So we need to use a more complex type
def eggs(cond:bool):
    x: Optional[List[int]]
    if cond:
        x = None # Now legal
    else:
        x: = []
    spam(x)

I don't think this improves readability.
Whether this is an acceptable change is debatable, but it does need some debate.

It limits the use of variables
==============================

In Python a name (variable) is just a binding that refers to an object.
A name only exists in a meaningful sense once an object has been assigned to it. Any attempt to use that name, without an object bound to it, will result in a NameError.

PEP 526 makes variables more than just bindings, as any rebinding must conform to the given type. This looses us some of the dynamism for which we all love Python.

Quoting from the PEP:
```
a: int
a: str # Static type checker will warn about this.
```
In other words, it is illegal for a checker to split up the variable, even though it is straightforward to do so.

However, without the type declarations,
```
a = 1
a = "Hi"
```
is just fine. Useless, but fine.

We should be free to add extra variables, whenever we choose, for clarity. For example,
    total = foo() - bar()
should not be treated differently from:
    revenue = foo()
    tax = bar()
    total = revenue - tax

If types are inferred, there is no problem.
However, if they must be declared, then the use of meaningfully named variables is discouraged.

[A note about type-inference:
Type inference is not a universal panacea, but it can make life a lot easier for programmers in statically type languages. Languages like C# use local type inference extensively and it means that many variables often do not need their type declared. We should take care not to limit the ability of checkers to infer values and types and make programmers' lives easier. Within a function, type inference is near perfect, failing only occasionally for some generic types. One place where type inference definitely breaks down is across calls, which is why PEP 484 is necessary.
]

It is premature
===============

There are still plenty of issues to iron out w.r.t. PEP 484 types. I don't think we should be adding more syntax, until we have a *precise* idea of what is required.

PEP 484 states:
"If type hinting proves useful in general, a syntax for typing variables may be provided in a future Python version." Has it proved useful in general? I don't think it has. Maybe it will in future, but it hasn't yet.

It seems confused about class attributes and instance attributes
================================================================

The PEP also includes a section of how to define class attributes and instance attributes. It seems that everything needs to be defined in the class scope, even it is not an attribute of the class, but of its instances. This seems confusing, both to human reader and machine analyser.

Example from PEP 526:

class Starship:

    captain: str = 'Picard'
    damage: int
    stats: ClassVar[Dict[str, int]] = {}

    def __init__(self, damage: int, captain: str = None):
        self.damage = damage
        if captain:
            self.captain = captain  # Else keep the default

With type hints as they currently exist, the same code is shorter and
doesn't contaminate the class namespace with the 'damage' attribute.

class Starship:

    captain = 'Picard'
    stats = {} # type: Dict[str, int]

    def __init__(self, damage: int, captain: str = None):
        self.damage = damage # Can infer type as int
        if captain:
            self.captain = captain # Can infer type as str


This isn't an argument against adding type syntax for attributes in general, just that the form suggested in PEP 526 doesn't seem to follow Python semantics.

One could imagine applying minimal PEP 526 style hints, with standard Python semantics and relying on type inference, as follows:

class Starship:

    captain = 'Picard'
    stats: Dict[str, int] = {}

    def __init__(self, damage: int, captain: str = None):
        self.damage = damage
        if captain:
            self.captain = captain

The PEP overstates the existing use of static typing in Python
==============================================================

Finally, in the rejected proposal section, under "Should we introduce variable annotations at all?" it states that "Variable annotations have already been around for almost two years in the form of type comments, sanctioned by PEP 484."
I don't think that this is entirely true.
PEP 484 was about the syntax for types, declaring parameter and return types, and declaring custom types to be generic. PEP 484 does include a description of type comments, but they are always annotations on assignment statements and were primarily intended for use in stub files.



Please don't turn Python into some sort of inferior Java.
There is potential in this PEP, but in its current form I think it should be rejected.

Cheers,
Mark.


_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to