Augument assignment versus regular assignment

A

Antoon Pardon

Just read what it says. `It is only evaluated once' is quite clear I would
say.

If it is so clear, why don't you explain it?
Your problem is that you thought __setitem__ is part of evaluation,

No I think the other way around. The evaluation is part of __setitem__
In so far as it makes sense to talk about the evaluation of a target
in python
but it isn't. It is part of assignment,

No the assignment is part of __setitem__
while __getitem__ is part of evaluation.

How can __getitem__ be part of the evaluation of col['t'] in
a statment like

col['t'] = 5

The language reference about augmented assigments is not only
talking about evaluating a language element as an expression,
it is also talking about evaluating that language element as
a target. Now I'm not so sure that it makes sense to talk about
evaluating a target in python, but I see no way to avoid that
interpretation in:

An augmented assignment expression like x += 1 can be rewritten as
x = x + 1 to achieve a similar, but not exactly equal effect. In
the augmented version, x is only evaluated once.

x is only evaluated once in a statement like: x+= 1
This suggests x is evaluated twice in a statement like: x = x + 1
The only way to eavlaute x twice in that statement is that
x is evaluated once as a target.
So the langauage reference is here talking about (among other things)
evaluating a target.

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.

This wording doesn't introduce two different kinds of evaluation
as the original wording of the language reference does.
 
A

Antoon Pardon

The problem with understanding augmented assignment is that it directs the
compiler and interpreter to do one or maybe two mostly invisible
optimizations. To me, the effective meaning of 'evalutating once versus
twice' is most easily seen in the byte code generated by what is, remember,
the reference implementation. What it does is what the
less-than-super-clear doc means.

But what does one do, if the question is raised whether or not the
code generated actually behaves as described by the language reference?

Shouldn't the language reference be clear enough to be understandable
without the help of byte code generated by the reference implementation?
Otherwise the reference implemenation is being used as part of the
language definition and then it can never be wrong.
 
P

Paul Boddie

Antoon said:
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. 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 += 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.

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.

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.

I doubt that this explanation is simple, clear or efficient enough for
the language reference, 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.

Paul
 
P

Piet van Oostrum

AP> If it is so clear, why don't you explain it?

I have done that in another thread.
AP> No I think the other way around. The evaluation is part of __setitem__
AP> In so far as it makes sense to talk about the evaluation of a target
AP> in python

How can evaluation be part of __setitem__? (If we talk about targets). The
LRM says clearly that it is part of assignment.
AP> No the assignment is part of __setitem__

__setitem__( self, key, value)
Called to implement assignment to self[key]
AP> How can __getitem__ be part of the evaluation of col['t'] in
AP> a statment like
AP> col['t'] = 5

It isn't, because there is a difference between evaluation in the
lefthandside and in the righthandside. See the description of assignment.
AP> The language reference about augmented assigments is not only
AP> talking about evaluating a language element as an expression,
AP> it is also talking about evaluating that language element as
AP> a target. Now I'm not so sure that it makes sense to talk about
AP> evaluating a target in python, but I see no way to avoid that
AP> interpretation in:

In the description of assignment the distinction is made for each case of
the lefthandside. So that for example when the lefthandside is a
subscription, only the primary and the index are evaluated, but no
__getitem__ is called.
AP> An augmented assignment expression like x += 1 can be rewritten as
AP> x = x + 1 to achieve a similar, but not exactly equal effect. In
AP> the augmented version, x is only evaluated once.
AP> x is only evaluated once in a statement like: x+= 1
AP> This suggests x is evaluated twice in a statement like: x = x + 1
AP> The only way to eavlaute x twice in that statement is that
AP> x is evaluated once as a target.
AP> So the langauage reference is here talking about (among other things)
AP> evaluating a target.
yes.

AP> What the language reference should have said IMO is that in case x
AP> is an attribute reference, index or slicing, the primary expression
AP> will be evaluated only once, as will be the index or slice in the
AP> two latter cases.

You should read the part about Augmented assignment statements after
carefully reading the part about assignments. Then you know already that
evaluation of the target is only about the primary and the index.
 
T

Terry Reedy

Antoon Pardon said:
But what does one do, if the question is raised whether or not the
code generated actually behaves as described by the language reference?

Shouldn't the language reference be clear enough to be understandable
without the help of byte code generated by the reference implementation?
Otherwise the reference implemenation is being used as part of the
language definition and then it can never be wrong.
 
T

Terry Reedy

Antoon Pardon said:
But what does one do, if the question is raised whether or not the
code generated actually behaves as described by the language reference?

One can just as well ask whether or not the docs actually describe the
behavior of the interpreter ;-). In this case, not as well as one might
like. Or, whether docs (and reasonable interpretation thereof) and
implementation match, which I claim they do it this case.
Shouldn't the language reference be clear enough to be understandable
without the help of byte code generated by the reference implementation?

Normally, code experiments, such as you attempted, should be enough. But,
as I said, trying to document mostly invisibly behavior is more difficult.
Based on looking at the byte code, I would put it this way: the difference
between assignment with duplicated source and target expressions and
augmented assigment with the same expression is that the interpreter
eliminates as much duplicate calculation as possible. But precisely what
that mean seems a bit interpreter dependent to me.

Should we expect a reference writen in (ambiguous) natural language to be
unambiguously clear? I think not; that is why formal grammers and
notations were invented. I learned Python with the doc in one window and
the interactive interpreter in another.
Otherwise the reference implemenation is being used as part of the
language definition

Exactly. People doing other implementations use it along with the docs.
and then it can never be wrong.

No, 'part of' does not mean 'governing'. A Python 'bug' is a discrepancy
between doc and code. Usually, normal experienced judgment is enough to
decide which is faulty and needs to be changed. Occasionaly, both are
plausibly correct and such cases get referred to Guido or the developer's
list for discussion and a decision.

Terry Jan Reedy
 
A

Antoon Pardon

I have done that in another thread.

Before I respond I would like you to be more specific
about where you gave that explanation. The subject
of the thread would be fine or a message-id perhaps.
 
A

Antoon Pardon

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 += 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 = a + 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 +=

is more effective than:

a = a +

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

a.append(b)

Because, i hope, we agree that a 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 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.
 
A

Antoon Pardon

One can just as well ask whether or not the docs actually describe the
behavior of the interpreter ;-). In this case, not as well as one might
like. Or, whether docs (and reasonable interpretation thereof) and
implementation match, which I claim they do it this case.

Well this dispute seems to boil down what is and what is not
involved in evaluating a target, and I have come to doubt that
target evaluation is even a meaningfull concept in python, so
maybe in order that I can understand how you come to that claim,
can you explain what a target evaluates to? So in a statement like

col['t'] = exp

What is the evaluation of col['t']?
Normally, code experiments, such as you attempted, should be enough. But,
as I said, trying to document mostly invisibly behavior is more difficult.
Based on looking at the byte code, I would put it this way: the difference
between assignment with duplicated source and target expressions and
augmented assigment with the same expression is that the interpreter
eliminates as much duplicate calculation as possible. But precisely what
that mean seems a bit interpreter dependent to me.

Should we expect a reference writen in (ambiguous) natural language to be
unambiguously clear? I think not; that is why formal grammers and
notations were invented. I learned Python with the doc in one window and
the interactive interpreter in another.

But there seems to be no formal system used for explaning the behaviour.
So I think one should take extra care in the language reference to
write in a way that is as clear as possible. IMO there is room for
improvement in the augmented assignment part. That is why I proposed
that the language reference would state that the primary of the
target would be evaluated only once, along with the index/key or slice.
Such wording avoids the notion of a target evaluation, which seems
trouble some and explains what kind of optimisations can be expected.
 
P

Paul Boddie

Antoon said:
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

In the notation given earlier, let us say that it would be this:

namespace = col
setitem(namespace, "t", exp)

Note that in my notation I use the term namespace to apply to actual
namespaces (locals, globals, classes, objects) as well as what I call
"itemspaces" (things which store items). In the above, we still obtain
the namespace first, but we don't attempt to fetch the item previously
stored at item "t" (if any was present).

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

a = a + b

This is where it gets interesting, even though it should not appear to
do so. We might consider writing this as follows:

setname(ns_target, "a", add(getname(ns_source, "a"), b))

Here, I've skipped over how b is obtained, but it'd be something like
getname(locals, "b") or getname(globals, "b"). Since recent versions of
Python perform some special tricks to disallow assignments involving
mixed namespaces (considering a is global and that the above code is in
a function), we probably can assume the same namespace is at work. But
really, the most pertinent question relates to the evaluation of the
namespaces themselves: a simple name binding operation involves the
local or global namespaces which can be obtained without side-effects.
Thus, the simple assignment above is mostly equivalent to the augmented
assignment...

a += b

....since ns_target == ns_source and their evaluation can be considered
free of side-effects. In other words, we can rewrite it thus:

assert ns_target == ns_source
namespace = ns_target
setname(namespace, "a", add(getname(namespace, "a"), b))
a.b = a.b + c

We could consider writing this:

setattr(a, "b", add(getattr(a, "b"), c))

Once again, I've skipped over how c is obtained, since it isn't central
to the assignment. As above, it appears that the namespace is the same
on both sides of the assignment (given Python's assignment rules),
although by using an opaque identifier the above example doesn't really
permit us to illustrate this. We could expand the identifier a to
investigate further:

setattr(getname(ns_target, "a"), "b", add(getattr(getname(ns_source,
"a"), "b"), c))

Which according to the above reduces to this:

setattr(getname(namespace, "a"), "b", add(getattr(getname(namespace,
"a"), "b"), c))

And to this:

ns_a = getname(namespace, "a")
setattr(ns_a, "b", add(getattr(ns_a, "b"), c))

Which shows that the augmented assignment is probably equivalent. See
below for a better example.
a = a + c


And again, we could consider writing this:

setitem(a, b, add(getitem(a, b), c))

Once again, I've skipped over how b and c are obtained. Consider this
as an exercise! ;-) And as noted above, the example doesn't really
permit us to illustrate this point - you could expand the terms and
produce something that suggests that this simple case is equivalent to
an augmented assignment.
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.

Quoting from the reference: "In the augmented version, x is only
evaluated once." Let us look in depth at some of the unillustrated
issues from above.
IMO the language reference sugest that the stament:

a +=


Here, we can be sure that the same namespace is involved:

namespace = a
setitem(namespace, i, add(getitem(namespace, i), ))
is more effective than:

a = a +


Whilst I, knowing that a appears twice and believing that a always
produces the same result, might write the same as above, let us
consider a more complicated expression instead of a (where the function
f returns a list):

f() = f() +

Here, since we can make no guarantees that f() evaluates to the same
thing every time it is called, we must evaluate it twice to honour the
intent of the statement:

setitem(f(), i, add(getitem(f(), i),

To see this clearly...

f1 = f()
f2 = f()
setitem(f1, i, add(getitem(f2, i), )

Meanwhile, in the case of the augmented assignment...

f() +=

....the author has more or less stated that he/she wants f() to be
evaluated only once - anything else would be surprising:

namespace = f()
setitem(namespace, i, add(getitem(namespace, i), b))
IMO it suggests that the augmented assignment version is
just as effective as:

a.append(b)

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


The rule is that if the namespace (what you call the primary, I think)
is mentioned once, it is evaluated only once.

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

Indeed. The language reference uses very simple opaque identifiers to
supposedly illustrate its point but, as we saw above, such examples
actually obstruct the path to understanding. That a simple identifier x
obtained from some namespace is not evaluated twice is almost
tangential to understanding the principles involved.

Paul
 
T

Terry Reedy

The claim, in reference to the CPython implementation, that you refer to
below.
Well this dispute seems to boil down what is and what is not
involved in evaluating a target,

Yes, and that is interpreter/implementation dependent.
and I have come to doubt that
target evaluation is even a meaningfull concept in python,

Abstractly, it is whatever the interpreter does before it actually attaches
an object to the name or slot. Again, the details are interpreter
dependent.
so maybe in order that I can understand how you come to that claim,

I looked at the CPython bytecode and saw that for augmented assigment, it
saved on the stack the internal information it needed for get and set
instead of recalculating it after the operation. This is what I expected
and what I think the docs imply.
can you explain what a target evaluates to?

The internal information the interpreter needs to do the assignment
(binding).
So in a statement like
col['t'] = exp
What is the evaluation of col['t']?

Try some personal introspection. When you act as a Python interpreter,
what do you do?
So I think one should take extra care in the language reference to
write in a way that is as clear as possible. IMO there is room for
improvement in the augmented assignment part.

I already agreed. I might someday suggest a change.

Terry Jan Reedy
 
A

Antoon Pardon

The claim, in reference to the CPython implementation, that you refer to
below.


Yes, and that is interpreter/implementation dependent.

Well I can agree that some things are implemantation dependent.
But shouldn't a language reference describe behaviour in terms or
implementation independent things?
Abstractly, it is whatever the interpreter does before it actually attaches
an object to the name or slot. Again, the details are interpreter
dependent.

Well I can sort of agree with this. IMO there are two possible views
here, (not necessarily mutual exclusive) But if you agree with the first
IMO the language reference shouldn't make use of the concept to
describe behaviour.

1) target evaluation is not a pythonic concept.

2) It is whatever the interpreter does before it actually
attaches an object, to a name/slot/... (in a primary).
I looked at the CPython bytecode and saw that for augmented assigment, it
saved on the stack the internal information it needed for get and set
instead of recalculating it after the operation. This is what I expected
and what I think the docs imply.


The internal information the interpreter needs to do the assignment
(binding).

Yes but that seems to be an entirly internal interpreter affair. If
you stay at the level of the byte code, you will not find any opcode
that will result in or manipulate a target evaluation.

If you look at the language reference for the assignment, you will
not find the notion of a target evaluation mentioned there either.

That is because as far as I can see, an assignment is essentially
a ternary operation in python. An assignment needs a (name)space/scope,
an index/key/name and an object and those three are combined into
an assignment. Sometimes it looks like only two elements
are given, but that is because the space is implicit in cases
of a rebinding, (the STORE_GLOBAL and STORE_FAST opcode).

Talking about a target evaluation IMO only makes sense if
you view an assigment as a binary operation.
So in a statement like
col['t'] = exp
What is the evaluation of col['t']?

Try some personal introspection. When you act as a Python interpreter,
what do you do?

I do the evaluation of the target in the __setitem__ method
(or the STORE_SUBSCR opcode).

Let as look what the compilor makes of it:
[blank lines added for clarity]
dis(compile("col['t'] = exp", '', 'single'))

1 0 LOAD_NAME 0 (exp)
3 LOAD_NAME 1 (col)
6 LOAD_CONST 0 ('t')

9 STORE_SUBSCR

The bytecodes at 0, 3 and 6 don't do any evaluation, they
just put things on the stack.

So what does the STORE_SUBSCR at location 9 do (or __setitem__)?

Well it will first do a number of preparations, like searching
for a bucket in a dictionary or a node in a tree or list, may
be even create one if a suitable wasn't available. And after
that is done, the object will be somehow attached.

So IMV those preparation before the attachment, belong to
whatever the interpreter does before it actually attaches
an object to a name/slot.

So the evaluation of the target is part of what is done by
STORE_SUBSCR or __setitem__.

Now you can object to the fact that I have divided the work
within an opcode. But if you do that, there seems to be
no place left to talk about a target evaluation in this
example.

So as a conclusion I would say one has two options:

1) View target evaluations as not a pythonic concept

2) Accept that target evaluation is done by STORE_SUBSCR/__setitem__
 
B

Boris Borcic

Antoon said:
The language reference doesn't talk about objects. And IMO you
should be carefull if you want to use the word "object" here.
In the line: "foo += 1", you can't talk about the object foo,
since foo will
possibly

be bound to a different object after the assignment
than it was bound to before.
witness
def __iadd__(self,other) :
self.append(other)
return self

[1]

while of course
False

Best, BB
 
T

Terry Reedy

Antoon Pardon said:
I do the evaluation of the target in the __setitem__ method
(or the STORE_SUBSCR opcode).

I meant mentally, in your mind ;-)
Let as look what the compilor makes of it:
[blank lines added for clarity]
dis(compile("col['t'] = exp", '', 'single'))

1 0 LOAD_NAME 0 (exp)
3 LOAD_NAME 1 (col)
6 LOAD_CONST 0 ('t')

9 STORE_SUBSCR

The bytecodes at 0, 3 and 6 don't do any evaluation, they
just put things on the stack.

So what does the STORE_SUBSCR at location 9 do (or __setitem__)?

Well it will first do a number of preparations, like searching
for a bucket in a dictionary or a node in a tree or list, may
be even create one if a suitable wasn't available. And after
that is done, the object will be somehow attached.

So IMV those preparation before the attachment, belong to
whatever the interpreter does before it actually attaches
an object to a name/slot.

So the evaluation of the target is part of what is done by
STORE_SUBSCR or __setitem__.

Now you can object to the fact that I have divided the work
within an opcode.

But I won't. The amount of duplication that can be factored out with
augmented assignment depends on the granularity of operations. And the
granularity of operations depends on the interpreter. Hence my claim that
the details are necessarily interpreter dependent.

Terry Jan Reedy
 
A

Antoon Pardon

But I won't. The amount of duplication that can be factored out with
augmented assignment depends on the granularity of operations.

I can agree with that. But until now each time I tried to
suggest that the STORE_SUBSCR or __setitem__ are involved
in the evaluation of the target, I was told I shouldn't
look at things that way.
And the
granularity of operations depends on the interpreter. Hence my claim that
the details are necessarily interpreter dependent.

Well my impression from reading the language reference is that
it suggests that a greater amount of duplication is factored out
than the granularity of the CPython implementation allows.

But since you already agreed that there is room for improvement
in the augmented assignment reference I will leave it at that.

I would like to thank everybody for their contributions, but I
think everything worth while has been said, so I will no longer
contribute to this thread.
 
T

Terry Reedy

Antoon Pardon said:
I can agree with that. But until now each time I tried to
suggest that the STORE_SUBSCR or __setitem__ are involved
in the evaluation of the target, I was told I shouldn't
look at things that way.

I don't think that I have said that, but only that a 'pragmatic' definition
is 'what actually is factored out'.
Well my impression from reading the language reference is that
it suggests that a greater amount of duplication is factored out
than the granularity of the CPython implementation allows.

Perhaps all that is meant to be promised is that function calls are not
duplicated, but if so, that could be much clearer. I would have to look at
more different types of expressions and their corresponding byte code
before suggesting anything particular.
I would like to thank everybody for their contributions, but I
think everything worth while has been said, so I will no longer
contribute to this thread.

Agreed.

Terry Jan Reedy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top