[Python-ideas] On evaluating features [was: Unpacking iterables for augmented assignment]

Franklin? Lee leewangzhong+python at gmail.com
Thu Sep 6 15:26:47 EDT 2018


n Thu, Sep 6, 2018 at 2:47 PM Chris Angelico <rosuav at gmail.com> wrote:
>
> On Fri, Sep 7, 2018 at 4:38 AM, Franklin? Lee
> <leewangzhong+python at gmail.com> wrote:
> > The following are equivalent and compile down to the same code:
> >     a, b, c = lst
> >     [a, b, c] = lst
> >
> > The left hand side is not an actual list (even though it looks like
> > one). The brackets are optional. The docs call the left hand side a
> > target list: https://docs.python.org/3/reference/simple_stmts.html#assignment-statements
> >
> > "Target list" is not a real type. You can't construct such an object,
> > or hold one in memory. You can't make a class that emulates it
> > (without interpreter-specific hacks), because it is a collection of
> > its names, not a collection of values.
>
> A target list is a syntactic element, like a name, or an operator, or
> a "yield" statement. You can't construct one, because it isn't an
> object type. It's not a "virtual type". It's a completely different
> sort of thing.

I didn't think I gave the impression that I was complaining about not
being able to construct it. I gave an explanation for how it isn't a
real type, because you asked how you could modify the behavior, and
because I wanted to give an explanation for more than just you.

There are constructs that correspond to types (such as slices and
functions). There are those that don't. We call `3:2` (in the right
context) a slice, even though it's technically a construct which is
compiled down to a `slice` object. I see no problem there.

I called it a "virtual type" and explained why I called it that. You
reject the use of that term, but you don't even acknowledge that I
gave reasons for it.

> > target_list.__iadd__ also does not exist, because target_list does not
> > exist. However, target_list can be thought of as a virtual type, a
> > type that the compiler compiles away. We can then consider
> > target_list.__iadd__ as a virtual operator, which the compiler will
> > understand but hide from the runtime.
> >
> > I was making the point that, because the __iadd__ in the example does
> > not refer to list.__iadd__, but rather a virtual target_list.__iadd__,
> > there is not yet a violation of the rule.
>
> What you're suggesting is on par with trying to say that:
>
> for += 5
>
> should be implemented as:
>
> current_loop.__iadd__(5)
>
> where "current_loop" doesn't really exist, but it's a virtual type
> that represents a 'for' loop.

I explained how target_list could be thought of as a special imaginary
type which only exists in the compiler's "mind", and then extended
that to an imaginary method on that type. Of course your example shows
absurdity: you didn't try to say how a for-loop is like an object in
the first place.

> That doesn't make sense, because there
> is no object in Python to represent the loop. There is no class/type
> that represents all loops, on which a method like this could be added.
> The word 'for' is part of the grammar, not the object model. And
> "target list" is the same. There's no way to attach an __iadd__ method
> to something that doesn't exist.

But I'm not using the word `for`. I am using constructs like `[a,b,c]`
(where it is not a list). At least use `(for x in y: z) += 5` as your
example. You're effectively accusing me of trying to make `[` (a
single token, not a full construct) an object.

Your argument here is that there is no Python object to represent a
loop, but that really means there's no _runtime_ object to represent a
loop. I already said that target lists don't exist in memory (i.e.
runtime).

"Target list" does exist, just not as a runtime type. It exists as an
abstraction not available to the runtime, and we can extend that
abstraction in ways not available to the runtime. That means that you
can't attach it during the runtime. It does not mean you can't reason
with it during compile-time.

> So for your proposal to work, you would need to break that rule, and
> give a *different* meaning to this.

It is not my proposal. I was questioning how there was a rule
violation about x+=y translating to `x = x.__iadd__(y)`. You're
talking about a different, made-up rule about how syntactical
constructs can't correspond to compile-time imaginary objects or
runtime objects. But there are syntactical constructs that DO
correspond to runtime types (slice, list, class), there are those
which don't but can (let's not get into that), there are those which
can stay compile-time (f-strings, target lists), and there are those
which probably can't be thought of as types at all (import).


More information about the Python-ideas mailing list