Allowing zero-dimensional subscripts
invalidemail at aerojockey.com
Fri Jun 9 05:22:27 EDT 2006
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:
> 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:
Is "1:2" an expression? How about "..."? When I enter 1:2 at the
Python prompt, I get a syntax error. The fact is, the documentation
here is either wrong or simplified or both. (I don't think it's a big
deal, actually: the real grammar has lots of complexity to handle
tricky cases that would needlessly complicate the reference manual for
a human reader.) So let's look at an excerpt the actual Python grammar
(from 2.4.3). You'll be happy to know subscription isn't used. :)
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
subscriptlist: subscript (',' subscript)* [',']
sliceop: ':' [test]
subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
testlist: test (',' test)* [',']
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
And there's a regular way to create an empty tuple... but not a
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
> 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.
More information about the Python-list