[Python-Dev] Reserve ':=' for type-inferred variable initialization (was PEP 572)

Fatty Morgan famopy at gmail.com
Thu Apr 26 14:00:55 EDT 2018

I would like to urge you to reconsider the use of the token ':='
for assignment expressions.

The natural interpretation of 'name := expr' is a PEP 526
type-annotated variable initialization 'name : T = expr' with the
type annotation T omitted, the tokens ':' and '=' coalesced, and
the implied type T inferred as 'type(expr)'.

There is an ongoing tendency to introduce possibilities for
static analysis into python, perhaps eventually resulting in a
statically typed variant of python were (optional) type
annotations are enforced (and used for optimizations), and it
would be a pity if this specific piece of obvious syntax had been
wasted on a comparatively unimportant feature.

The following should probably be discussed in python-ideas and
would only be relevant for a more distant future, but while I
have your attention, here are a couple of thoughts:

Distinguishing in a rather unobtrusive way (no 'var' or 'let')
the initialization of a previously unbound variable 'name := expr'
and the re-assignment of a previously bound variable 'name = expr'
would be beneficial in itself (this has been discussed before but
AFAIK not with this syntax). For example, 'global' and 'nonlocal'
would be redundant and could be deprecated.

The use of variable initializations with explicit type
annotations as in PEP 526 would only be required in situations
where the declared type is deliberately different from the
inferred type, e.g.
'any_var: object = 42; any_var = "foo"; #OK, no TypeError'.
In the majority of cases a simple 'name := expr' would be
sufficient and type-safe.

Destructuring initialization, e.g., 'a,b,c: int = range(3)' or
'a,b,c := range(3)', is possible (the annotated or inferred type
refers not to the type of the iterable but to the generated
type).  If it were forbidden (i.e., only a single name-variable
allowed) PEP 572 with ':=' could be simply implemented by parsing
'name := expr' as an expression rather than a statement (assuming
it is OK to introduce 'name' into the current scope) but
destructuring initialization appears to be the more important
feature and would make assignment expressions with ':='

Implementation would be straightforward if 'name := expr' were
lowered to 'name: auto = expr' where the newly introduced abstract
type 'auto' simply acts as a token informing compile-time and/or
run-time what to do. An explicit type annotation with type
'auto' could be allowed and would help to teach the feature.

More information about the Python-Dev mailing list