Re: [Python-Dev] Visibility scope for "for/while/if" statements

Hello Josiah, print j JC> In regards to 'for' loops, they have always done that, there is code JC> that relies on that behavior, and changing behavior would unnecessarily JC> break code. I mentioned it below: while unconditional changing the behaviour will definitely break a lot, something like "import strict" would help those ones who rate such behaviour enough error-prone to reconsider proceeding using Python at all. JC> Further, you should clarify what you would want this mythical non-leaky JC> for loop to do in various cases. What would happen in the following JC> case? JC> i = None JC> for i in ...: JC> ... JC> print i JC> ... assuming that the loop executed more than once? Would you always JC> get 'None' printed, or would you get the content of the last variable? As for me (if my humble opinion is useful for you), the best would be to 1. assume that a loop variable is always newly-declared for this loop, 2. all variables first declared inside the loop are local to this loop. Thus, your example falls to case 1: "i" variable is newly declared for this loop. Well, we don't reuse old value of i to start the iteration from a particular place, like below? i = 5 for i in [3,4,5,6,7]: print i, More general, the variables could be assumed local only to the *same or higher* indentation level. JC> What about: JC> x = None JC> for i in ...: JC> x = f(i) JC> ... JC> print x JC> Would 'x' be kept after the loop finished executing? case 2: "x" variable is declared already. And if there is no "x = None" line, it should tell "name 'x' is not defined". Unless we are prone to funny "uncertainly defined" cases, if some variable is defined inside an "in" in the loop. JC> I would imagine in your current code you are running something like JC> this: JC> i = #some important value JC> ... #many lines of code JC> for i in ...: JC> ... JC> #you access the 'i' you bound a long time ago JC> In this case, you are making a common new programmer mistake by using JC> the same variable name for two disparate concepts. Nah, here is my error-case: I made several loops, one by one, using the "i" variable for looping. Then in the latest loop I changed the "i" name to more meaningful "imsi" name in the "for" declaration and whenever I found inside the loop. As I use "i" name *for loops exclusively*, I didn't wittingly reuse the same name for different purposes. The problem was that I missed one occurance of "i" variable inside the loop code, so it gained the same value (from the completion of previous loop) throughout all the "imsi" loop. And the interpreter didn't notice me that "I am using the undefined variable" (since it is considered defined in Python), as accustomed from other languages. That's my sorrowful story. JC> If the 'i' that was JC> initially bound was important through the lifetime of the scope, you JC> should have named it differently than the 'i' that was merely a loop JC> variable. I'm pretty happy that I didn't ever made a list comprehension with "i" variable inside the loop over "i" variable. While I wasn't aware of these side-effects, it would be even harder spottable. Now I'll look more carefully at copy-pasting list comprehensions, in every case examining all of the lower-indent variables for not to clash. JC> I will also point out that in general, not leaking/exposing/etc. such JC> variables would necessarily slow down Python. Why? I agree, this is one of obvious advantages of absence of pseudo-namespaces (wasting the resources to allocation and removal of variables, etc). Though in case of presence of pseudo-namespaces, it an easily be emulated by initializing the variable first-time on the highest-level of indentation. But for the "performance-oriented/human-friendliness" factor, Python is anyway not a rival to C and similar lowlevellers. C has pseudo-namespaces, though. JC> Python semantics seem to have been following the rule of "we are all JC> adults here". I always believed that the programming language (as any computer program) should slave to the human, rather than a human should slave to the program. JC> Generally though, Python follows a common C semantic of variable leakage. JC> C Code: JC> int i; // required in some versions of C JC> for (i=0;i<10;i++) { JC> ... JC> } "for (int i = 0; i < 10; i++)" works fine nowadays. JC> Again: test your assumptions. If your untested assumptions are wrong, JC> don't complain that the language is broken. In my case, as I explained already, it was not a assumption but an uncatched mistype, which is usually catched in other languages due to the presence of "pseudo-namespaces" (and in other languages I even accustomed to enforce the locality of temporary variables by explicitly setting the logically independent blocks of code within the curly braces). I always test the doubtful pieces before use. But *I don't dare to tell that the language is broken*. The existing behaviour has its own pros, and I also don't want a lot of code to be broken by easy behaviour change. What upsets me is the absence of alternatives (as the lack of flexibility) for the new code, especially with the fact that current behaviour mismatches with many of currently popular languages and habits learned from them. JC> Also: python-dev is a mailing list for the development /of/ Python. JC> Being that your questions as of late have been in the realm of "why does JC> or doesn't Python do this?", you should go to python-list (or the JC> equivalent comp.lang.python newsgroup) for answers to questions JC> regarding current Python behavior, and why Python did or didn't do JC> something in its past. I'm sorry for wasting the time of developers. For "for/while/if" statements, I just had an idea which (I believed) could be useful for many peoples, and could be very useful for such a human-orienter language as Python is (actually, this idea is borrowed from another language, but only partly - only in the area of ability to have "for" and "while" inside the single loop expression), so I though that the best people to estimate it should be the ones who potentially could implement this (provided they like it). For this conversation, the explained just looked to me as language-level problem (especially for list comprehensions), so I had to beg a workaroung/explanation/fix to it also from the language creators. If they don't consider it a problem and don't have a workaroung - sorry again for wasting your time, then that's indeed only my problem and I'll try to cope with it myself. I really didn't want to "claim and blame". What I asked and proposed was intended to be useful not only for myself, but - I believed - for many people, especially newcomers after the other languages. -- С уважением, Alexander mailto:maa_public@sinn.ru

Alexander Myodov wrote:
So (since you're talking about "if" as well as "for" and "while") you're suggesting that x = 0 if foo(): x = 1 else: x = 2 should always leave x == 0? Or that the same bit of code, without the first line, should always leave x undefined?
Right. And some of us humans *don't want* the change you're proposing. For what it's worth, I think it might well have been better if "for" and comprehensions had made their loop variables block-local; especially comprehensions. But making every for/while/if introduce a new level of scoping would be horrible. Perhaps you think it's what you want, but I think if you tried it for a month then you'd change your mind. -- g

Alexander Myodov <maa_public@sinn.ru> wrote: [snip Alexander Myodov complaining about how Python works]
Maybe you don't realize this, but C's while also 'leaks' internal variables... int i = 0, j; while (i != 1) { i++; j = 5; } printf("%i %i\n", i, j); If you haven't yet found a good use for such 'leakage', you should spend more time programming and less time talking; you would find (quite readily) that such 'leaking' is quite beneficial.
So you mistyped something. I'm crying for you, really I am.
C does not have pseudo-namespaces or variable encapsulation in for loops. Ah hah hah! Look ladies and gentlemen, I caught myself a troll! Python does not rival C in the performance/friendliness realm? Who are you trying to kid? There is a reason why high school teachers are teaching kids Python instead of Pascal, Java, etc., it's because it is easier to learn and use. On the performance realm, of course Python is beat out by low-level languages; it was never meant to compete with them. Python does what it can for speed when such speed does not affect the usability of the language. What you are proposing both would reduce speed and usability, which suggests that it wasn't a good idea in the first place.
Your beliefs were unfounded. If you look at every programming language, there are specific semantics and syntax for all of them. If you fail to use and/or understand them, the langauge will not be your 'slave'; it will not run correctly, if at all.
"for (int i = 0; i < 10; i++)" works fine nowadays.
I'm sorry, but you are wrong. The C99 spec states that you must define the type of i before using it in the loop. Maybe you are thinking of C++, which allows such things.
Test your ideas on comp.lang.python first, when more than a handful of people agree with you, come back. - Josiah

On Thursday 2005-09-22 20:00, Josiah Carlson wrote: [Alexander Myodov:]
I think you've misunderstood Alex here; he's saying that Python and C don't occupy the same region of the spectrum that runs from "high performance, human-unfriendly" to "lower performance, human friendly". Which is correct, unlike some other things he's said :-).
No, Alex is right on this one too. Maybe you are thinking of C89, which forbids such things. 6.8.5.3 The for statement [#1] Except for the behavior of a continue statement in the loop body, the statement for ( clause-1 ; expr-2 ; expr-3 ) statement and the sequence of statements { clause-1 ; while ( expr-2 ) { statement expr-3 ; } } are equivalent (where clause-1 can be an expression or a declaration).123) ... 123Thus, clause-1 specifies initialization for the loop, possibly declaring one or more variables for use in the loop; expr-2, the controlling expression, specifies an evaluation made before each iteration, such that execution of the loop continues until the expression compares equal to 0; expr-3 specifies an operation (such as incrementing) that is performed after each iteration. If clause-1 is a declaration, then the scope of any variable it declares is the remainder of the declaration and the entire loop, including the other two expressions. (This is from a late draft of the C99 spec; I'm fairly sure the final version is no different.) -- g
participants (3)
-
Alexander Myodov
-
Gareth McCaughan
-
Josiah Carlson