[Python-ideas] PEP 572: Assignment Expressions (post #4)

Chris Angelico rosuav at gmail.com
Wed Apr 11 11:10:25 EDT 2018


On Thu, Apr 12, 2018 at 12:46 AM, Clint Hepner <clint.hepner at gmail.com> wrote:
>
>> On 2018 Apr 11 , at 9:25 a, Chris Angelico <rosuav at gmail.com> wrote:
>> I have no idea what the "in" keyword is doing here, but somehow it
>> isn't being used for the meaning it currently has in Python. Does your
>> alternative require not one but *two* new keywords?
>
> Just one; I don't see using ``in`` here to be any more or a problem than was
> reusing ``if``, ``then``, and ``else`` for conditional expressions.

> ``in`` already has two different uses: as a Boolean operator (two, actually, with ``not in``)
> and as part of the various ``for`` constructs. IMO, I don't see adding this third meaning
> to be a problem.
>
> With ``let``, the scope extends as far right of ``in` as possible:
>
>     let NAME = EXPR in let OTHERNAME = EXPR in EXPR
>
> is equivalent to
>
>     let NAME = EXPR in (let OTHERNAME = EXPR in EXPR)

A 'for' loop has the following structure:

for targets in expr:

To the left of the 'in', you have a list of assignment targets. You
can't assign to anything with an 'in' in it:

>>> for (x in y) in [1]: pass
...
  File "<stdin>", line 1
SyntaxError: can't assign to comparison

(Removing the parentheses makes this "for x in (y in [1])", which is
perfectly legal, but has no bearing on this discussion.)

In contrast, the way you're using it here, it's simply between two
arbitrary expressions. There's nothing to stop you from using the 'in'
operator on both sides of it:

let x = (a in b) in (b in c)

This would make the precedence tables extremely complicated, or else
have some messy magic to make this work.

>>>> Augmented assignment is not supported in expression form::
>>>>
>>>>>>> x +:= 1
>>>>     File "<stdin>", line 1
>>>>       x +:= 1
>>>>           ^
>>>>   SyntaxError: invalid syntax
>>>
>>> There's no reason give for why this is invalid. I assume it's a combination
>>> of 1) Having both += and +:=/:+= would be redundant and 2) not wanting
>>> to add 11+ new operators to the language.
>>
>> And 3) there's no point. Can you give an example of where you would
>> want an expression form of augmented assignment?
>
> I wouldn't want one :). I'm just suggesting that the PEP include something to the
> effect of "We're not adding augmented assignment expressions because...".

Does the document really need to say that it isn't needed?

>> The 'where' example is broadly
>> similar to rejected alternative 3, except that you're removing the
>> colon and the suite, which means you can't create more than one
>> variable without figuring some way to parenthesize.
>
> I agree that `where` *should* be rejected; I don't really like them in Haskell, either.
> I only listed ``let`` here because I assume it *will* be rejected due to its requiring
> a new keyword, no matter how much I think adding a new keyword is warranted.

In round 3 of this PEP, I was focusing on listing all plausible
variants. I'm now focusing more on an actually-viable proposal, so
myriad alternatives aren't as important any more.

>>>> With assignment expressions, why bother with assignment statements?
>>>> -------------------------------------------------------------------
>>>>
>>>> The two forms have different flexibilities.  The ``:=`` operator can be used
>>>> inside a larger expression; the ``=`` operator can be chained more
>>>> conveniently, and closely parallels the inline operations ``+=`` and friends.
>>>> The assignment statement is a clear declaration of intent: this value is to
>>>> be assigned to this target, and that's it.
>>>
>>> I don't find this convincing. I don't really see chained assignments often enough
>>> to worry about how they are written, plus note my earlier question about the
>>> precedence and associativity of :=.
>>
>> If you don't use them, why would you care either way? :)
>
> I just mean this seems like a weak argument if you are trying to convince
> someone to use assignment statements. "Assuming I never use chained assignments,
> why should I use ``=`` instead of ``:=`?"

Fair enough. The most important part is the declaration of intent. By
using an assignment *statement*, you're clearly showing that this was
definitely intentional.


>> Your "let... in" syntax is kinda interesting, but has a number of
>> problems. Is that the exact syntax used in Haskell, and if so, does
>> Haskell use 'in' to mean anything else in other contexts?
>
> I don't believe ``in`` is used elsewhere in Haskell, although Python
> already has at least two distinct uses as noted earlier.
>
> In Haskell, the ``let`` expression (like much of Haskell's syntax) is
> syntactic sugar for an application of lambda abstraction. The general form
>
>     let n1 = e1
>         n2 = e2
>     in e3
>
> is syntactic sugar for
>
>     let n1 = e1
>     in let n2 = e2
>     in e3
>
> where multiple bindings are expanded to a series of nested expressions. The single
> expression
>
>     let n1 = e1 in e2
>
> itself is transformed into
>
>     (\n1 -> e2) e1
>
> (or translated to Python, (lambda n1: e2)(e1)).

Makes sense. And if someone actually wants expression-local name
bindings, this is the one obvious way to do it (modulo weirdness
around class scope). This would not solve the if/while situation, and
it wouldn't solve several of the other problems, but it does have the
advantage of logically being expression-local.

ChrisA


More information about the Python-ideas mailing list