Augument assignment versus regular assignment

Antoon Pardon apardon at forel.vub.ac.be
Tue Jul 18 05:24:32 EDT 2006


On 2006-07-17, Paul Boddie <paul at boddie.org.uk> wrote:
> Antoon Pardon wrote:
>>
>> What the language reference should have said IMO is that in case x
>> is an attribute reference, index or slicing, the primary expression
>> will be evaluated only once, as will be the index or slice in the
>> two latter cases.
>
> I think the difficulty here for the author of this particular section
> of the reference is in describing the mechanisms at work whilst keeping
> the description at a conceptual level which can be directly connected
> to the source text in a program.

Sure! However the author of the augmented assignment reference uses
a concept that seems not be a pythonic concept: a target evaluation.
Call it an lvalue, a lefthand evaluation if you prefer, but in
the assignment reference it is never mentioned. Each time the
word evaluation is used, it is the evaluation of an expression, never
a target. Sure sometimes such a expression is part of a target, but
the evaluation never reaches a point where the result is the evaluation
of a target: So why doesn't the autor of the augmented assignment reference
limit himself to the same concepts used in the assignment reference?

Now maybe I'm just not bright enough, so maybe you can explain what
something like col['t'] is evaluated to in a statement like:

  col['t'] = exp

> However, apart from providing a vague
> intuition about how augmented assignment must work, the description
> doesn't answer all questions effectively, particularly in cases where
> the actual assignments are not simple local/global name binding
> operations.
>
> One way to consider augmented assignment is as a statement formulated
> in the following way:
>
> setvalue(namespace, name, op(getvalue(namespace, name), expr))
>
> Consider an augmented assignment on a local name:
>
> a += b
>
> This could be phrased as follows:
>
> setname(locals, "a", add(getname(locals, "a"), b))
>
> Or really:
>
> setname(locals, "a", add(getname(locals, "a"), getname(locals, "b")))
>
> Consider an augmented assignment on an attribute:
>
> a.b += c
>
> This could also be phrased similarly:
>
> setattr(a, "b", add(getattr(a, "b"), c))
>
> And consider an augmented assignment on an item:
>
> a[b] += c
>
> This too is phrased similarly:
>
> setitem(a, b, add(getitem(a, b), c))
>
> So, as long as you're willing to accept that the setvalue class of
> operations (setname, setattr, setitem) aren't really evaluating the
> target of the assignment - strictly, the thing being replaced in the
> assignment - then only the getvalue class of operations (getname,
> getattr, getitem) are causing the evaluation of the target. And since
> setname is just a normal name binding assignment which we know doesn't
> cause the target to be evaluated, we can assume that the other
> operations in that class behave similarly.

Well maybe I'm missing your point entirely but would you be so friendly,
as to rephrase the following statements too:

  a = a + b
  a.b = a.b + c
  a[b] = a[b] + c

Because as far as I can see the rephrasing of these statements will
result in exactly the same results as their augmented assignment
counter parts. So following your logic above, we would have to
come to the conclusion that the "targets" of these statements are
evaluated once too. This while the language reference suggests
they are evaluated twice.

IMO the language reference sugest that the stament:

  a[i] += [b]

is more effective than:

  a[i] = a[i] + [b]

IMO it suggests that the augmented assignment version is
just as effective as:

  a[i].append(b)

Because, i hope, we agree that a[i] is evaluated only
once here!

So we have here three statements all which result
in a similar result one in which the
number of evaluations of a[i] is under dispute,

one in which the number of evaluations is suggested
to be two

one in which the number of evaluations is one.

Yet the work done in the augmented version of this
example is almost the same as in the normal assignment,
the difference is negligible IMO and both version
differ about the same with the append version which
will have to do about half what the other versions had to
do, depending on how expensive the __xetitem__ methods
are.


> Now, one aspect of evaluation has been skipped in the above
> explanation: what if we have a "complicated" expression on the left
> hand side? Consider this:
>
> a.f().x += y
>
> We could naively write this as follows:
>
> setattr(a.f(), "x", add(getattr(a.f(), "x"), y))
>
> However, it looks like we are evaluating at least part of the left hand
> side twice. Thus, we need to be a bit clearer about what really
> happens:
>
> namespace = a.f()
> setattr(namespace, "x", add(getattr(namespace, "x"), y))
>
> In order to avoid double evaluation, we first obtain the target
> namespace (or itemspace, I suppose). Then, we perform the operations as
> stated above.

Yes, and what you are doing here is eliminating the double evaluation
of the primary. In a statement like a.f().x = ... the a.f() part
is the primary according to the assignment reference.

> So, to conclude, augmented assignment involves the evaluation of any
> expression which gives the target namespace (trivial in the case of
> local/global name binding, non-trivial otherwise), then a compound
> operation of the form given above involving two classes of operations,
> each providing operations to act on names, attributes and items.

This seems not be complete, if the target is a list, there is no target
namespace. That is why I used "primary" in my proposal, because
it catches all cases and it is also the term used in the assigment
reference.

> I doubt that this explanation is simple, clear or efficient enough for
> the language reference,

Would you mind explaning, what you think is not simple, clear or
efficient enough about my proposed wording? Just curious.

> but then any explanation shouldn't be
> constrained in terms of complexity in a way that, for example, a
> tutorial explanation should be. Despite cries of "you must get it now!"
> from various quarters, I think this thread has been informative, and
> I'd like to thank you for bringing this matter to the group's
> attention, Antoon.

Your welcome.

-- 
Antoon Pardon



More information about the Python-list mailing list