On Dec 18, 1:59 am, Steven D'Aprano <steve +comp.lang.pyt...@pearwood.info> wrote: > 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".
Casts or conversions are a runtime concept; im talking about declarations. That seems to be the source of your confusion. > 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. Yes, the variable tail is being (re)declared here. Thats exactly why I call it a type constraint. Im not sure what the CS books have to say on the matter, I guess this use of the term entered my lexicon through the C# developer team. Either way, you seem to be the only one who does not grok my intended meaning, so I suggest you try reading it again. > > 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. for x in range is syntactic sugar for a series of assignments to x; x is an unconstrained variable that will indeed take anything it gets; the semantics of what comes after 'x' does in no way depend on x itself. head, tail = l and head, *tail = l mean something completely different, and the only difference is a constraint placed on tail, which forces the semantics to be different; the righthand side, or what is to be assigned, is identical. Of course one can just regard it as syntactic sugar for head, tail = unpackheadandtailaslist(l); but the syntactic sugar achieves that same end through a type constraint on tail. Really. > 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? You are jumping to conclusions about my opinion which aren't supported by my visible behaviour. What evidence do you have that I ever even said any such thing? > > 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(). Because you wish to keep nitpicking about my usage of the term 'type constraint' (even though you have not introduced an alternative term yourself), or because you actually disagree with the content of my message? -- http://mail.python.org/mailman/listinfo/python-list