unintuitive for-loop behavior

Chris Angelico rosuav at gmail.com
Fri Sep 30 12:39:23 EDT 2016


On Sat, Oct 1, 2016 at 12:36 AM, Grant Edwards
<grant.b.edwards at gmail.com> wrote:
> On 2016-09-30, Steve D'Aprano <steve+python at pearwood.info> wrote:
>
>> To me, "make for-loops be their own scope" sounds like a joke feature out of
>> joke languages like INTERCAL. I'm not aware of any sensible language that
>> does anything like this.
>
> In C99 a for loop has its own namespac:
>
>   int main(void)
>   {
>     for (int i=0; i<5; ++i)
>       printf("i=%d\n",i);
>   }
>
> If you try to access 'i' outside the for loop, it's an error, because
> it doesn't exist in the file, global or 'main' namespace.  It only
> exists in the for-loop's namespace.

I believe that's the same semantics as C++ uses, and I agree, it's
very convenient. Among other things, it means that nested loops behave
more like they do in Python, with independent iterators:

int main(void)
{
    for (int i=0; i<5; ++i)
    {
        printf("%d:", i);
        for (int i=0; i<3; ++i)
            printf(" %d", i);
        printf("\n");
    }
}

Now, granted, this is not something I would ever actually recommend
doing, and code review is absolutely justified in rejecting this...
but it's a lot better than pure function-scope variables, where you'd
get stuck in an infinite loop. Obviously the inner 'i' shadows the
outer 'i', but that's the only actual conflict between them.

> I think that's an absolutely brilliant feature, and I use it a _lot_
> when writing C code.  I'm a big fan of minimizing the lifetime/scope
> of variables. I wish if/then/else did the same thing:
>
>   if ((r=some_function()) != R_SUCCESS)
>     printf("some_function() failed with status %d\n",r);

No particular reason not to. Ditto 'while' loops:

while (int r=some_function())
    ..

I agree with minimizing scope, but only where it's practical to do so.
In Python, it simply isn't. Like C, Python has infinitely nested
scopes; unlike C, Python requires explicit 'nonlocal' declarations in
order to assign to something in an outer scope, ergo the convenience
of not declaring local variables translates into extreme inconvenience
of working with overly-narrow scopes. To put it more simply: Scope is
cheap in C, but expensive in Python.

ChrisA



More information about the Python-list mailing list