[Python-Dev] [PEP] += on return of function call result
Luke Kenneth Casson Leighton
lkcl@samba-tng.org
Fri, 16 May 2003 14:24:51 +0000
On Fri, May 16, 2003 at 08:07:23AM -0400, Andrew Koenig wrote:
> ark> Why can't you do this?
>
> ark> for t in range(5):
> ark> for r in range(10):
> ark> foo = log.setdefault(r,'')
> ark> foo += "test %d\n" % t
>
> Luke> after running this code,
>
> Luke> log = {0: '', 1: '', 2:'', 3: '' ... 9: ''}
>
> Luke> and foo equals "test 5".
>
> Then that is what foo would be if you were able to write
>
> log.setdefault(r,'') += "test %d\n" % t
>
> as you had wished.
hmm...
..mmmm...
you're absolutely right!!!
> Luke> if, however, you do this:
>
> Luke> for t in range(5):
> Luke> for r in range(10):
> Luke> foo = log.setdefault(r,[])
> Luke> foo.append("test %d\n" % t)
>
> Luke> then empirically i conclude that you DO end up with the
> Luke> expected results (but is this true all of the time?)
>
> I presume that is because you are now dealing with vectors instead
> of strings. In that case, you could also have written
>
> for t in range(5):
> for r in range(10):
> foo = log.setdefault(r,[])
> foo += ["test %d]n" % t]
>
> with the same effect.
>
> Luke> the reason why your example, andrew, does not work, is
> Luke> because '' is a string - a basic type to which a pointer is
> Luke> NOT returned i presume that the foo += "test %d"... returns a
> Luke> DIFFERENT result object such that the string in the dictionary
> Luke> is DIFFERENT from the string result of foo being updated.
>
> Well, yes. But that is what you would have gotten had you been allowed
> to write
>
> log.setdefault(r,"") += <whatever>
>
> in the first place.
[i oversimplified in the example, leading to all the communication
problems.
the _actual_ usage i was expecting is based on {}.setdefault(0, []) += [1,2]
rather than setdefault(0, '') += 'hh'
]
> Luke> can anyone tell me if there are any PARTICULAR circumstances where
>
> Luke> foo = log.setdefault(r,[])
> Luke> foo.append("test %d\n" % t)
>
> Luke> will FAIL to work as expected?
>
> It will fail if your expectations are incorrect or unrealistic.
... that sounds like a philosophical or "undefined" answer rather
than the technical one i was seeking
... but it is actually quite a _useful_ answer :)
to put the question in a different way, or to say again, to put
a different, more specific, question:
can anyone tell me if there are circumstances under which the second
argument from setdefault will SOMETIMES be copied instead of returned
and SOMETIMES be returned as-is, such that operations of the type
being attempted will SOMETIMES work as expected and SOMETIMES not?
> Luke> andrew, sorry it took me so long to respond: i initially
> Luke> thought that under all circumstances for all types of foo,
> Luke> your example would work.
>
> But it does! At least in the sense of the original query.
where the sense was mistaken, consequently the results are not,
as you rightly pointed out, not as expected.
> The original query was of the form
>
> Why can't I write an expression like f(x) += y?
>
> and my answer was, in effect,
>
> If you could, it would have the same effect as if you had written
>
> foo = f(x)
> foo += y
>
> and then used the value of foo.
>
> Perhaps I'm missing something, but I don't think that anything you've said
> contradicts this answer.
based on this clarification, my queries are two-fold:
1) what is the technical, syntactical or language-specific reason why
I can't write an expression like f(x) += y ?
2) the objections that i can see as to why f(x) += y should not be
_allowed_ to work are that, as andrew points out, some people's
expectations of any_function() += y may be unrealistic,
particularly as normally the result of a function is discarded.
however, in the case of setdefault() and get() on dictionaries,
the result of the function is NOT discarded: in SOME instances,
a reference is returned to the dictionary item.
under such circumstances, why should the objections - to disallow
{}.setdefault(0, []) += [] or {}.get([]) += [] - stand?
l.