[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.