Allowing zero-dimensional subscripts

Carl Banks invalidemail at aerojockey.com
Fri Jun 9 19:31:18 EDT 2006


Steve Holden wrote:
> Carl Banks wrote:
> > Steve Holden wrote:
> >
> >>Hey, I have an idea, why don't we look at the language reference manual
> >>instead of imagining how we think it might work!
> >
> >
> > I don't know.  Sounds risky.
> >
> >
> >
> >>In section 3.2 we find:
> >>
> >>
> >>"""
> >>Tuples
> >>The items of a tuple are arbitrary Python objects. Tuples of two or more
> >>items are formed by comma-separated lists of expressions. A tuple of one
> >>item (a `singleton') can be formed by affixing a comma to an expression
> >>(an expression by itself does not create a tuple, since parentheses must
> >>be usable for grouping of expressions). An empty tuple can be formed by
> >>an empty pair of parentheses.
> >>"""
> >>
> >>So it seems that your speculation is false. Section 2.6 specifically
> >>defines "[" and "]" as delimiters. Section 5.3.2 defines a subscription
> >>(a term I've not really grown to love, but what the heck) as
> >>
> >>subscription ::= primary "[" expression_list "]"
> >>
> >>and section 5.12, which defines expression_list, explicitly says
> >>
> >>"""An expression list containing at least one comma yields a tuple.""".
> >>
> >>So it would appear that while your change might be very convenient to
> >>allow you to refer to scalar values as zero-dimensional arrays, it
> >>doesn't really fit into Python's conceptual framework. Sorry.
> >
> >
> > Yes, that would appear to be so.  You would have a point... if the
> > documentation were correct.  Only it's not.
> >
> > According to the reference manual, the rule for an expression_list is:
> >
> > expression_list ::= expression ( "," expression )* [","]
> >
> > But take the following legal Python subscripted array:
> >
> > a[1:2,...,3:4]
> >
> But the element inside the brackets there isn't  an expression-list,
> it's a slicing (see section 5.3.2).

Section 5.3.2 says an expression-list is what's inside the brackets
(you quoted this rule yourself).  Section 5.12 says an expression-list
consissts of comma-separated expressions.  But 1:2 and ... aren't
expressions.  I only brought this up to point out that the docs were
not exactly correct, and in particular it swept an important
distinction (for this nit-picky discussion) under the rug.


[snip]
> > trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
> > subscriptlist: subscript (',' subscript)* [',']
> > sliceop: ':' [test]
> > subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
> > testlist: test (',' test)* [',']
> >
> The simplification of the grammar is explicitly documented:
[snip]

Nice to know.


> > Clearly, the grammar rule used for list subscript is different from the
> > one used for list of expressions (for some reason, what an ordinary
> > person would call an expression is called a "test" in the grammar,
> > whereas "expr" is a non-short-circuiting expression).
> >
> > So there's a regular way to create non-empty tuples, and a subscript
> > way.
> >
> > And there's a regular way to create an empty tuple... but not a
> > subscript way.
> >
> > So I'd say this change fits the conceptual framework of the tuple quite
> > well; in fact, it makes subscript tuples more parallel to their regular
> > counterparts.
>
> Although this debate is beginning to make me sound like one, I am really
> not a language lawyer.  However, I should point out that what you are
> describing as a "tuple" should more correctly be described as a
> "slice-list" once you include slices or an ellipsis as elements.
> Slicings are described, as I am fairly sure you know, in section 5.3.3.

No, I don't think I am.  I was careful to distinguish between grammar
rules and tuples.  subscriptlist and testlist are grammar rules.
"Evaluation" of both of these guys can create a tuple.  The two grammar
rules have exactly the same relationship to the tuple: an testlist with
a comma creates a tuple, a subscriptlist with a comma creates a tuple.

But note neither testlist nor subscriptlist can create an empty tuple.
You need a special case for that--only there's no special special case
for subscripts.  (The visual effect, as OP noted, is that you need
parentheses for the empty tuple, but never need them for any other
subscript.)


> >>One further point: if you really do conceptualize scalars as
> >>zero-dimensional arrays, where is the value conceptually stored?
> >
> > Think of it this way: an array with n-dimensions of length 3 would have
> > 3**n total entries.  How many entries would a 0-dimensional array have?
> >  3**0 == 1.
> >
> > Numeric has had zero-dimensional arrays for a long time, and has had no
> > problem storing them.  Think of the rule for accessing an element of an
> > array: it's a base pointer + sum (indices*stride) for all indices.  Now
> > generalize it down to zero: there are no indices, so the scalar is
> > stored at the base pointer.
>
> I can see that, and it doesn't seem unreasonable. Fortunately your
> persistence has goaded me into determining the point that *did* seem
> unreasonable to me: you were falsely trying to equate slicings and tuples.

The OP might have been; I wasn't.  But that's fair enough; everyone
should be clear on what's happening behind the scenes.

> Having said all of which, there probably *is* a case for proposing that
> an empty slicing become syntactically acceptable, so why not write the
> PEP and go for it?

Well, I'm only +0 on it, so I'll leave it to the OP.  I was mainly
concerned with how the language reference was obscuring what I felt
were important distinctions.


Carl Banks




More information about the Python-list mailing list