var or inout parm?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Fri Dec 12 19:00:24 EST 2008


On Fri, 12 Dec 2008 08:43:31 -0800, sturlamolden wrote:

> On Dec 12, 5:13 pm, Steve Holden <st... at holdenweb.com> wrote:
> 
>> > It should be the tuple's __setitem__ that was invoked here, not
>> > __iadd__, or the parser is faulty.
>>
>> OK, so now you are proposing to alter the parser, and possibly the
>> implementation of the INPLACE_ADD opcode in eval.c, so can you give us
>> the patch for those, please?
> 
> What? Take a look at the code again:
> 
> mytuple[0] += 1
> 
> should never attempt an __iadd__ on mytuple.
> 
> A sane parser would see this as:
> 
> tmp = mytuple.__getitem__(0)
> tmp = tmp.__iadd__(1)
> mytuple.__setitem__(0, tmp) # should this always raise an exception?

It is quite problematic if you do that. You've already pointed that out 
yourself, by asking if "should this always raise an exception?". With the 
behaviour you're asking for, there's ambiguity is what is allowed and 
what isn't. You can try making __setitem__ cleverer, as in your earlier 
post, but then:

t = (1, 2, 3)
t[0] += x

sometimes succeeds, sometimes fails, depending on the value of x.

And worse:

t[0] = y

also sometimes succeeds.

It's not clear that those occasional successes are actively harmful, but 
nor is it clear that prohibiting them is harmful either. The best you get 
from it is the ability to mutate mutable items in a tuple, but you can do 
that already:

t = ([], None)
x = t[0]
x += ["mutated"]

So the current tuple implementation gives us consistent behaviour and 
simplicity without preventing you from mutating elements if you really 
want to. The only real cost is if you do this:

t[0] += ["mutated"]

you get an error and a mutation. Certainly a gotcha, but I wouldn't 
describe it as a bug: it's pretty much unavoidable if you want to avoid 
treating tuples as a special case.



>> Discussion of such behavior as a "bug" is also pejorative, since the
>> current semantics are the way they are by design.
> 
> Right, this bug is by design. You learned that phrase from a guy in
> Redmond?

No. It merely means that just because you think it is a bug doesn't make 
it so. It may even mean that there is no perfect solution, that *any* 
behaviour on tuples containing mutable objects will be considered broken 
by some people under some circumstances.

Trade-offs in software design are inevitable. There's little gain from 
your proposal, and some cost, and the problem you are trying to solve 
isn't a problem in practice. So if it's a bug, it's an insignificant one, 
not worth fixing because the fix will invariably cause more problems than 
the bug.



-- 
Steven



More information about the Python-list mailing list