> > One problem is that it's really hard to design the bytecode so that > > this can be implemented. The problem is that the compiler sees this: > > > > a[i] += x > > > > and must compile bytecode that works for all cases: a can be mutable > > or immutable, and += could return the same or a different object as > > a[i]. It currently generates code that uses a STORE_SUBSCR opcode > > (store into a[i]) with the saved value of the object and index used > > for the BINARY_SUBSCR (load from a[i]) opcode. It would have to > > generate additional code to (a) save the object retrieved from a[i] > > Isn't that already lying about on the stack somewhere? Didn't you have to > have it in order to invoke "+= x" on it? (I'm totally ignorant of Python's > bytecode, I'll be the first to admit) Getting that object is the easy part. > > (b) compare the result to it using the 'is' operator, and (c) pop some > > stuff of the stack and skip over the assignment if true. That could > > be done, but the extra test would definitely slow things down. > > As was suggested by someone else in the thread I referenced, I was thinking > that a new bytecode would be used to handle this. It has to be faster to do > one test in 'C' code than it is to re-indexing into a map or even to do the > refcount-twiddling that goes with an unneeded store into a list. > > > A worse problem is that it's a semantic change. For example, > > persistent objects in Zope require (under certain circumstances) that > > if you modify an object that lives in a persistent container, you have > > to store it back into the container in order for the persistency > > mechanism to pick up on the change. Currently we can rely on a[i]+=x > > and a.foo+=x to do the assigment. Under your proposal, we couldn't > > (unless we knew that the item was of an immutable type). > > That's right. I would have suggested that for persistent containers, the > object returned carries its own write-back knowledge. But that's not how it works. Giving each container a persistent object ID is not an option. > > That is such > > a subtle change in semantics that I don't want to risk it without > > years of transitional warnings. > > Hah, code breakage. The purity of the language must not be compromised, at > any cost! Well, ok, if someone's actually using this extra step I guess you > can't change it on a whim... > > > Personally, I'd rather accept that if you have a = ([], [], []), > > a[1]+=[2] won't work. You can always write a[1].extend([2]). > > It's your choice, of course. However, it seems a little strange to have > this fundamental operation which is optimized for persistent containers but > doesn't work right -- and (I assert without evidence) must be slower than > neccessary -- in some simple cases. The pathological/non-generic cases are > the ones that make me think twice about using the inplace ops at all. They > don't, in fact, "just work", so I have to think carefully about what's > happening to avoid getting myself in trouble. You have a habit of thinking too much instead of using common sense. :-) --Guido van Rossum (home page: http://www.python.org/~guido/)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4