[Python-Dev] accumulator display syntax

Alex Martelli aleaxit at yahoo.com
Fri Oct 17 12:52:34 EDT 2003

On Friday 17 October 2003 06:03 pm, Phillip J. Eby wrote:
> Because it's arguably bad coding style to use slices or indexes on an
> object in order to perform a function on the indexes supplied.  Wouldn't
> you find a program where this held true:
>     TimesTwo[2] == 4
> to be in bad style?  Function calls are for transforming arguments,
> indexing is for accessing the contents of a *container*.  Top(10) is not a

Yes, I would find _gratuitous_ use of indexing where other means are
perfectly adequate to be in bad style.  On the other hand, where Python
'wants' me to use indexing for other purposes, I already do:

>>> class Eval:
...   def __getitem__(self, expr): return eval(expr)
>>> print '2 + 2 is %(2 + 2)s' % Eval()
2 + 2 is 4

and given we don't have a better way to "interpolate expressions in
strings", I don't feel particularly troubled by this, either.

> container, it has nothing in it, and neither does TimesTwo.  I suppose you
> could argue that TimesTwo is a conceptual infinite sequence of even
> integers, but for most of the proposed accumulators, similar arguments
> would be a *big* stretch.

Yes; any pure function is mathematically a mapping, but arguing for
general confusion on that score between indexing and function calls
would be stretchy indeed, I agree.  Before we had iterators and
generators, I did use "indexing as pure function call" to get infinite
sequences for use in for loops (to be terminated by break or return
when appropriate), but I'm much happier with iterators for this
purpose (they keep state, so, having dealt with some prefix of a
sequence in a for loop, I still have the sequence's tail intact for
possible future processing -- that's often VERY useful to me! --
AND it's often SO much easier to compute "the next item" than it
is to compute "the i-th item" for an arbitrary natural i).

> Yes, what you propose is certainly *possible*.  But again, if you really
> needed an iterator as an index, you can right now do:
> sum[ [x*x for x in blaap] ]

Actually, I need to use parentheses on the outside and brackets only
on the inside -- I assume that's what you meant, of course.

If the iterator is finite, and memory consumption not an issue, sure.
An infinite iterator would in any case not be suitable for sum (but it
_might_ be suitable for other uses, of course).  I truly dislike the way
foo([...]) _looks_, with those ([ and ]) pairs, but, oh well, not _every_
frequently used construct can look nice, after all.

> And if there are gencomps, you could do the same.  So, why single out
> subscripting for special consideration with regard to generator
> comprehensions, thus forcing clever tricks of questionable style in order
> to do what ought to be function calls?

I guess I let my dislike of ([ ... ]) get away with me:-).  If gencomps use
your proposed syntax, I'll have no problem whatsoever coding

sum((yield: x*x for x in blaap))

particularly since the (( ... )) don't look at all bad;-).  Seriously, what 
I'm after is the functionality: since the _syntax_ seemed to be the
stumbling block, I thought of an alternative syntax that seemed fine
to me (not any more of a stretch of the concept of indexing than the
Eval class above, or the not-so-long-ago use of __getitem__ to get
infinite sequences in for loops) and proposed it.  If your (yield: ...)
syntax is approved instead, I'll be first in line to cheer:-).

> I shudder to think of trying to have to explain Top(10)[...] to a Python
> newbie, even if they're an experienced programmer.  Because Top(10) isn't a
> *container*.  I suppose a C++ veteran might consider it an ugly operator
> overloading hack...  and they'd be right.  Top(10,[...]) on the other hand,
> is crystal clear to anybody that gets the idea of function calls.

I agree it's clearer -- a tad less flexible, as you don't get to do separately
    selector = Top(10)
and then somewhere else
but "oh well", and anyway the issue would be overcome if we had currying
(we could be said to have it, but -- I assume you'd consider
    selector = Top.__get__(10)
some kind of abuse, and besides, this 'currying' isn't very general).


More information about the Python-Dev mailing list