On Monday 27 October 2003 04:11 pm, Guido van Rossum wrote: ...
I don't think you'll ever *have* to explain this anyway, as long as := and += use the same rules to find their target (I'd even accept
Actually, I'd like to make a := ... an error when there's an a = ... in the same function, so it can't be exactly the same rules for a += ... in my opinion.
I'm *not* saying that I like := (so far I still like 'global x in f'
I think the main weakness (for me) of := and other approaches that try to force you to say you're rebinding a nonlocal each time you do it is beginning to show: there are already well-established rules for deciding whether a bare name is local or not, and those rules have
There are, but they represent a wart (according to AMK's python-warts page, http://www.amk.ca/python/writing/warts.html , and I agree with him on this, although NOT with his suggested fix of having the compiler "automatically adding a global when needed" -- I don't like too-clever compilers that make subtle inferences behind my back, and I think that the fact that Python's compiler doesn't is a strength, not a weakness).
The "well-established rules" also cause one of the "10 Python pitfalls" listed at http://zephyrfalcon.org/labs/python_pitfalls.html . My personal experience teaching/consulting/mentoring confirms this, although I, personally, don't remember having been bitten by this (but then, I recall only 2 of those 10 pitfalls as giving trouble to me personally, as opposed to people I taught/advised/etc: mutable default arguments, and "loops of x=x+y" performance traps for sequences).
It seemed to me that introducing := (or other approaches that require explicit denotation of "I'm binding a nonlocal here") was a chance to FIX the warts/pitfalls of those "already well-established rules". Albeit with a heavy heart, I would consider even a Rubyesque stropping of nonlocals (Ruby uses $foo to mean foo is nonlocal, others here have suggested :foo, whatever, it's not the sugar that matters most to me here) preferable to using "declarative statements" for the purpose. Oh well.
always worked "at a distance". The main reason for disallowing rebinding nonlocals in the past has been that one of those rules was "if there's a bare-name assignment to it it must be local (unless there's also a global statement for it)" (and I couldn't find a satisfactory way to add a nonlocal declarative statement and I didn't think it was a huge miss -- actually I still think it's not a *huge* miss).
Agreed, not huge, just probably marginally worth doing. Should it make "declarative statements" more popular and widely used than today's bare "global", I don't even know if it would be worth it.
I don't like declarative statements. I don't understand why you like them here, when, in your message of Thursday 23 October 2003 06:25:49 on "accumulator display syntax", you condemned a proposal "because it feels very strongly like a directive to the compiler". "A directive to the compiler" is exactly how "global" and other proposed declarative-statements feel to me: statements that don't DO things (like all other statements do), but strictly and only are "like a directive to the compiler".
and it doesn't seem to me that the two extra keystrokes are to be considered a substantial price to pay.
That's the argument that has always been used against += by people who don't like it. The counterargument is that (a) the savings in typing isn't always that small, and (b) += *expresses the programmer's
The saving in typing is not always small _when on the left of the augmented assignment operator you have something much more complicated than just a bare name_. For example,
counter[current_row + current_column * delta] += current_value
Without += this statement would be too long, and it would be hard to check that the LHS and RHS match exactly -- in practice one would end up breaking it in two,
current_index = current_row + current_column * delta counter[current_index] = counter[current_index] + current_value
which IS still substantially more cumbersome than the previous version using += . But this counterargument does not apply to uses of += on bare names: the saving is strictly limited to the length of the bare name, which should be reasonably small.
thought better*. Personally I expect that as soon as nonlocal rebinding is supported in any way, people would be hugely surprised if += and friends were not.
We could try an opinion poll, but it's probably worth it only if this measure of "expected surprise" was the key point for your decision; if you're going to prefer declarative statements anyway, there's no point going through the aggravation.
If we do rely on augmented assignment being "rebinding":
def accumulator_saturating(n=0, m=100): def increment(i): if n > m: n = i else: n += i return n return increment
the error becomes a runtime rather than compile-time one, and does take a (small but non-zero) time to discover it.
Hah. Another argument *against* rebinding by :=, and *for* a nonlocal declaration. With 'nonlocal n, m' in increment() (or however it's spelled :-) the intent is clear.
I disagree that the example is "an argument for declarations": on the contrary, it's an argument for := without "rebinding +=".
The erroneous example just reposted gives a runtime error anyway (I don't know why I wrote it would give a compile-time error -- just like a bare "def f(): x+=1" doesn't give a compile-time error today, so, presumably, wouldn't this reposted example). If "n := n + i" WAS used in lieu of the augmented assignment, THEN -- and only then -- could we give the preferable compile- time error, for forbidden mixing of "n = ..." and "n := ..." in different spots in the same function.