On 12/9/2014 12:03 AM, Terry Reedy wrote:
Roy Smith wrote:
Chris Angelico wrote:
def myzip(*args):
iters = map(iter, args)
while iters:
res = [next(i) for i in iters]
yield tuple(res)
Ugh. When I see "while foo", my brain says, "OK, you're about to see a
loop which is controlled by the value of foo being changed inside the
loop".
What is nasty to me is that to understand the loop, one must do a whole
program analysis to determine both that 'iters' is not rebound and that
the list it is bound to is not mutated. To do the later, one must not
only read the loop body, but also preceding code to make sure the list
is not aliased.
> iters is empty if and only if args is empty.
If args is empty, iters should not be created.
if args:
iters = ...
while True
... (return on exception)
makes the logic clear.
Once the logic is clear and 'localized', even a simple compiler like
CPython's can see that this is a loop-forever construct and that the
loop test is unnecessary. So it can be removed.
>>> dis("while a: b+=1")
1 0 SETUP_LOOP 20 (to 23)
>> 3 LOAD_NAME 0 (a)
6 POP_JUMP_IF_FALSE 22
9 LOAD_NAME 1 (b)
12 LOAD_CONST 0 (1)
15 INPLACE_ADD
16 STORE_NAME 1 (b)
19 JUMP_ABSOLUTE 3
>> 22 POP_BLOCK
>> 23 LOAD_CONST 1 (None)
26 RETURN_VALUE
>>> dis("while True: b+=1")
1 0 SETUP_LOOP 13 (to 16)
>> 3 LOAD_NAME 0 (b)
6 LOAD_CONST 0 (1)
9 INPLACE_ADD
10 STORE_NAME 0 (b)
13 JUMP_ABSOLUTE 3
>> 16 LOAD_CONST 1 (None)
19 RETURN_VALUE
'while 1' and 'while "exception not raised"' are similarly condensed.
This leaves only the initial test of the argument.
--
Terry Jan Reedy
--
https://mail.python.org/mailman/listinfo/python-list