Pythonification of the asterisk-based collection packing/unpacking syntax

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sat Dec 17 19:59:45 EST 2011


On Sat, 17 Dec 2011 06:38:22 -0800, Eelco wrote:

> Type constraints:
> 
> In case the asterisk is not used to signal unpacking, but rather to
> signal packing, its semantics is essentially that of a type constraint.

"Type constraint" normally refers to type restrictions on *input*: it is 
a restriction on what types are accepted. When it refers to output, it is 
not normally a restriction, therefore "constraint" is inappropriate. 
Instead it is normally described as a coercion, cast or conversion. 
Automatic type conversions are the opposite of a constraint: it is a 
loosening of restrictions. "I don't have to use a list, I can use any 
sequence or iterator".


In iterator unpacking, it is the *output* which is a list, not a 
restriction on input: in the statement:

head, *tail = sequence

tail may not exist before the assignment, and so describing this as a 
constraint on the type of tail is completely inappropriate.



> The statement:
> 
>     head, tail = sequence
> 
> Signifies regular unpacking. However, if we add an asterisk, as in:
> 
>     head, *tail = sequence
> 
> We demand that tail not be just any python object, but rather a list.

We don't demand anything, any more than when we say:

for x in range(1, 100):

we "demand" that x is not just any python object, but rather an int.

Rather, we accept what we're given: in case of range and the for loop, we 
are given an int. In the case of extended tuple unpacking, we are given a 
list.



> This changes the semantics from normal unpacking, to unpacking and then
> repacking all but the head into a list.

Aside: iterator unpacking is more general than just head/tail unpacking.

>>> a, b, *var, c, d, e = range(10) 
>>> print(a, b, c, d, e, var)
0 1 7 8 9 [2, 3, 4, 5, 6]


You are jumping to conclusions about implementation details which aren't 
supported by the visible behaviour. What evidence do you have that 
iterator unpacking creates a tuple first and then converts it to a list?


> It may be somewhat counter-intuitive to think of this as a type
> constraint, since python is after all a weakly-typed language. 

The usual test of a weakly-typed language is that "1"+1 succeeds (and 
usually gives 2), as in Perl but not Python. I believe you are confusing 
weak typing with dynamic typing, a common mistake.


[...]
> The aim of this PEP, is that this type-constraint syntax is expanded
> upon. We should be careful here to distinguish with providing optional
> type constraints throughout python as a whole; this is not our aim.

Iterator unpacking is no more about type constraints than is len().



-- 
Steven



More information about the Python-list mailing list