4 ms·
Because the code that closes over can be arbitrarily complicated. I simply used code that only called a function with a single argument as a minimal example. A
by Blikkentrekker 6y ago
Because the code that closes over can be arbitrarily complicated. I simply used code that only called a function with a single argument as a minimal example.
Apart from that, your code technically does not do the same thing as it calls the inner function with two arguments, whereas mine simply discards the second argument.
- bb88 6y agoBut your argument is about scoping. Replacing the lambda with a function inside the for loop shows the closure plainly. So your complaint can't be about scoping, or maybe this is a bad example of your argument. Maybe your complaint is about the fact that statements inside a lambda isn't called until the lambda is called. But again, lambda's are just functions, and closures are closures. Or maybe your argument is that closures are easy to make in python, which is true. But that doesn't mean the language is bad, since lots of languages use closures.
- Blikkentrekker 6y agoNo, my complaint is, as said, hat for-loops in Python do not create a block scope as they do in about any other language. The closure is simply a way to illustrate that but there are many other problems such as this one: x = something # some lines of code for x in iterator: # something # try to use x again here # x has been re-assigned by the loop In about any other language, the loop would create it's own scope, and thus shadow the existence of the outer `x`, rather than re-assigning it.
- bb88 6y agoSo your first example was clearly a bad example. This was a better example. But even so, this is a lousy example since x is already defined at the top. So the for loop could theoretically use the defined x already. I think what you're looking for is something akin to the following in C: int x = 5; for (int x=0; x<10; x++) { int y = x; } But I would argue that this is terrible C code since the inner x shadows the outer scope leading to confusion as to which x the loop is iterating on. But you could also write the for loop like this: for (x<0; x<10; x++) { ... } So C doesn't dictate the scope of the loop which could be argued by your standards, even more confusing than python. Python just says your scope is just function level. Subtle C code changes can create scoping bugs. So even the scoping example your trying to use is fraught with issues for new developers. Is "function-level" scoping better than "C-style" scoping say? I tend to think that function level scoping forces developers to simplify their code as it discourages symbolic shadows.
- Blikkentrekker 6y agoNo, the first example illustrates the fundamental problem that all iterations of the loop share the same scope rather than a new one each. In your example, the variable `x` is also shared with all iterations of the loop. Rather, it is more so as so in C, like syntax what is the common approach: while(1) { int x = next(iterator) if(STOPITER) { break } /* code that uses x */ } Every iteration of the loop receives a brand new `x` rather than re-assigning the old `x`, this problem is illustrated by creating a closure that closes over the `x`, for which the expected behavior is not that the `x` is then assigned to another value on the next iteration of the loop. The only way to achieve this in Python is to create an ad-hoc function which is passed `x` as a formal parameter, for every new function call in Python does create a new scope rather than simply re-assigning to the last one.
- bb88 6y agoI would argue that code that is sensitive to scope is bad code no matter which language it's written in, since now you're constantly asking "When does a variable leave scope." If I change the scope of a variable, it causes a subtle change that breaks the closure. In that case I would prefer to be explicit that the closure "wraps" a new instance of the variable rather than relying upon implicit language behavior to guarantee the scope is correct. As python says in "import this": "Explicit is better than implicit."
- Blikkentrekker 6y ago> I would argue that code that is sensitive to scope is bad code no matter which language it's written in Then you have argued that using any form of functions or subroutines in any language is bad design. > since now you're constantly asking "When does a variable leave scope." If I change the scope of a variable, it causes a subtle change that breaks the closure. Yes, that is what one must ask oneself as a programmer and that is what programmers who have not been taught wrong practices by having used Python as their introduction are instinctively constantly asking themselves. Python programmers must also ask themselves this whenever they use functions and Python comes with a variety of ugly hacks around it's initial wanton design by a programmer who clearly does not understand scope how he originally designed it such as `nonlocal`. Inside any function in Python there are four kinds of variables in terms of their scope: normal, formal, global, and nonlocal, each of them has a different scope and the programmer best be mindful of which is which as he codes, because they have widely different semantics and because Python has the same syntax for assignment and initialization and this difference especially creates very different interpretations for those four types. > In that case I would prefer to be explicit that the closure "wraps" a new instance of the variable rather than relying upon implicit language behavior to guarantee the scope is correct. I feel that you have a fundamental misunderstanding of what a closure or function is if you think it even possible for it to wrap a new instance of a variable. You seem to be of the same misunderstanding as another user above that `let x = x;`-esque behavior would affect this issue in any way rather than be an irrelevant line. > As python says in "import this": "Explicit is better than implicit." Not only is this very rich coming from a language that uses exceptions for flow control, and the same syntax for initialization and assignment, it's also irrelevant and not a matter of explicitness versus implicitness. Whether wrapping variables would be implicit or explicit in this context would not have solved the issue at all. Even if Python mandated explicit wrapping or made shadowing illegal, which some languages do, for which there is argument to be had, it would not change this subtle bug at all.