PEP 289: Generator Expressions (please comment)

Rocco Moretti roccomoretti at hotpop.com
Tue Oct 28 15:29:36 EST 2003


Alex Martelli wrote:
> Werner Schiendl wrote:
>>Alex Martelli wrote:
>>
>>>No, but, in all cases where the lack of parentheses would make the
>>>syntax unclear, you do need parentheses even today to denote tuples.
>>>Cfr:
>>>    [1,2,3]
>>>versus
>>>    [(1,2,3)]
>>>a list of three items, versus a list of one tuple.
>>
>>ok, but that's the whole point (1,2,3) *is* a tuple.
> 
> It's a tuple in parentheses.
> 

I've never bought the argument that "comma's make the tuple." All the 
explanations I've seen seem to be a posteriori rationalizations by 
people who are being a bit too "clever." (... no offense intended Alex.)

I base my interpretation of this on the fact that (as I understand it) 
the comma explanation was brought up *after* the relevant semantics of 
Python were coded.

To me, tuple packing/unpacking is a special case, not a general feature 
of tuple notation. I claim as evidence the recent c.l.p thread about
"for d[n] in mylist:", etc. the ability to use a comma separated list in 
such situations is a special case - it isn't *really* a tuple, the fact 
that it is a tuple is an implementation detail. (Note that it may be a 
*required* implementation detail, but that's neither here or there ...)

Of course, I'll change my opinion if Guido comes out and says that he 
consciously intended all along for tuples to be defined by commas, and 
the parenthesis were just there to disambiguate - but my guess is that 
it's instead convergent evolution of separate ad hoc devices.

> The parentheses are only necessary when the syntax would otherwise
> be unclear, and THAT is the whole point.

"In the face of ambiguity, refuse the temptation to guess."

I'd say that by allowing for some instances the ability for tuples to go 
around naked, the unparenthesized form is *still* ambiguous. The 
argument "Well, for this case it can't be a tuple, because if it *was* a 
tuple then it would be ambiguous" makes my head hurt. It seems a little 
disingenuous to define language semantics by defining what something 
*isn't*.

> The difference between tuples and the proposed syntax for
> genexps is that genexp are going to _require_ parentheses
> around them -- unless the parentheses already "happen" to be
> there, i.e., in the frequent case in which the genexp is the
> only argument to a function or type call.  Basically, that's
> because, even though the _compiler_ would have no problems,
> Guido judges that a _human reader_ might.

I was going to write a big rant on the fact that I have difficulties in 
reading the genex as a "chunk", and how there should be some sort of 
bracketing required, but Guido used/uses/will use his time machine to 
deflate 9/10 of my argument.

So let me see if I have this correct:

(Long Answer)

Genex's are required to have parenthesis around them except when they 
would yield double parenthesis i.e. ((...)) - and the only place where 
this is relevant is in function calls with one argument, or with 
creating a tuple. (As genex's as base class lists and as a parameter 
list would be illegal.) But with creating a tuple, you have to have a 
comma to create a singleton, so that case doesn't matter either.

As a parenthetical (sic.) note, the only other cases of 'double 
brackets' are {(...)} and [(...)], as python doesn't use <...> as 
brackets. The first is illegal anyway - you can't create a dictionary 
with just a genex. The second is covered in the PEP - that is:

"""
[x for x in S]    # This is a list comprehension.
[(x for x in S)]  # This is a list containing one generator
                   # expression.
"""
*and* the former is depreciated in favor of list(<genex>).

(Short Answer)

Parenthesis are required around genex's except when they are the *only* 
parameter to a function.

(Tuples?)

My only other concern is with tuples without parenthesis in the single 
parameter to a function case, as they might be confused with multiple 
parameter lists.

As I understand, the genex syntax is:

expression1 "for" expression2 "in" expression3a
or
expression1 "for" expression2 "in" expression3b "if" expression4

If expression1 is a tuple, it is required to have parenthesis. (Current 
behavior of list comprehensions.)

If expression2 is a tuple, it can have parenthesis absent. (As it is 
delimited between for and in.) Is this the same for genex's?

If expression3a is a tuple, it will be required to have parenthesis in 
genex's. (They are currently optional for list comps.)

What about a tuple for expression3b? Are parenthesis required here?

Although it doesn't really make much sense, expression4 can be a tuple. 
The PEP doesn't say, but am I correct in assuming that in such a 
condition, expression4 would require parenthesis? (Parenthesis are 
required for list comps, so I'm guessing the answer is yes.)

(Current Final short answer)

Parenthesis are required around genex's except when they are the *only* 
parameter to a function. If either the first or last expression in a 
genex is a tuple, they must have parenthesis around them.

...

I was against genex's without brackets, but with the requirements Guido 
added, I'm not quite sure about it. My guess is that it's a "time will 
tell" situation. I'll pass the buck to Guido.

-Rocco





More information about the Python-list mailing list