[Python-Dev] Product iteration

Eric S. Raymond esr@thyrsus.com
Tue, 25 Jul 2000 15:28:32 -0400


Moshe Zadka <moshez@math.huji.ac.il>:
> 
> A large part of the problem in list comprehensions (I think) is that we
> need to allow more then one "for" term, so we can iterate over the product
> of several lists. Why not solve that the same way we solved the parallel
> iteration problem, by using a function, called, say, "product".
> 
> Then list comprehensions can limited to be (in pseudo formal grammar):
> 
> '[' expr 'for' var 'in' seq [ 'if' pred ] ']'
> 
> Such that "var" can be anything that can today be in a for loop, e.g.,
> 
> (x, (y, z))
> 
> Then we wouldn't have the irksome problem of how for's and if's intermix:
> the predicate at the end can be an and'ed sequence of predicates.

*KLANNGGG!!!*   <-- the sound of the sacred two-by-four of enlightenment 
                    belatedly whacking Eric upside the head

Dammit, I should have seen this sooner; the whole debate about parallel
loops and zip() was a flare-lit clue.  Gentlemen, we've been going
entirely down the wrong path trying to express list comprehensions via
a syntax in imperative style.  What they want to be is an applicative 
sublanguage in functional style -- and mostly about data composition
rather than the expression of iteration per se.

zip() is part of this.  Finding a way to handle conditionals ain't hard; 
in fact, it's already in the language!  The right way to say

[x**2 for x in range(1, 99) if isprime(x)]

is like this:

[x**2 for x in filter(isprime, range(1, 99)]

Look at the implications: there is no longer any need for special
syntax (or for python-dev debates over special syntax, or newbie
confusion over special syntax) on the right side of the for.  We get
all the power of list comprehensions from one simple [for ... in ...]
construct exactly parallel to the for ... in that Python programmers
already understand.

So instead of trying to fix list comprehensions with syntactic hacks,
we can extend it by having a properly rich and orthogonal set of
constructor functions.  

filter, zip, product, and lambda are good enough to cover anything the
presently proposed comprehension syntax can handle.  But there's a
difference, because unfreezing and extending a syntax is a heckuva
lot harder than inventing new functional constructors.

If you notice that this looks a lot like LISP or F or Haskell, you win.
These languages got comprehensions right on the basis of a lot of
experience in depth.  We can learn from their example.
-- 
		<a href="http://www.tuxedo.org/~esr">Eric S. Raymond</a>

An armed society is a polite society.  Manners are good when one 
may have to back up his acts with his life.
        -- Robert A. Heinlein, "Beyond This Horizon", 1942