Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-19 Thread Stephen J. Turnbull
Steven D'Aprano writes:

 > What key combination do I need to type to get ≜ in the following editors 
 > please? I tried typing \triangleq but all I got was \triangleq.

Your implied point is correct IMO, but all of the editors and
applications mentioned that I've used are perfectly happy with any
characters delivered by the OS.  So your question should be "what key
combination do I use ... in the following OSes and/or GUIs:" (I don't
have a list).  Ditto fonts (MS fonts tend to work crappily on Mac in
my experience, at least in Word and Excel).  I note that currently
there is heated debate on the Fedora lists about distributing the base
OS with decent East Asian font support, and I think the majority are
*opposed* (on the grounds that the size increase is noticable).  I've
also noticed that the recommended fonts on Linux seem to have been in
flux for decades, and even differ across distros much of the time.

Either way, teaching how to augment your OS is not the business of
Python, so we should stick to a reasonable approximation to the least
advanced environment, which is (TA-DA!) that of the U.S.



___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-17 Thread Steven D'Aprano
On Tue, Apr 17, 2018 at 03:36:34AM +1000, Chris Angelico wrote:

[further aggressive snippage] *wink*

> > Chris, I must admit that I'm utterly perplexed at this. Your example is
> > as far as from a complex assignment target as you can possibly get. It's
> > a simple name!
> >
> > i := i + 1
> >
> > The target is just "i", a name.
> 
> Thanks so much for the aggressively-trimmed quote. For once, though,
> TOO aggressive. What you're focusing on is the *unrolled* version of a
> two-line loop. Look at the actual loop, please, and respond to the
> actual question. :|

Ah, I never even picked up on the idea that the previous while loop was 
connected to the following bunch of calls to input(). The code didn't 
seem to be related: the first was already using -> syntax and did not 
use input(), the second used := syntax and did.


> >> The calls to input were in a while loop's header for a reason.
> >> Ignoring them is ignoring the point of assignment expressions.
> >
> > What while loop? Your example has no while loop.
> 
> Not after it got trimmed, no. Here's what I actually said in my original post:
> 
> while (read_next_item() -> items[i + 1 -> i]) is not None:
> print("%d/%d..." % (i, len(items)), end="\r")
> 
> Now, if THAT is your assignment target, are you still as happy as you
> had been, or are you assuming that the target is a simple name?

I'll give the answer I would have given before I read Nick's comments 
over on Python-Dev: sure, I'm happy, and no, I'm not assuming the 
target is a simple name.

But having seen Nick's response on Python-Dev, I'm now wondering whether 
this should be limited to simple names.

Further discussion in reply to Nick's post over on Python-Dev please.



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-17 Thread Thautwarm Zhao
> Hey!  I did not propose "?". Read the explanation in parenthesis.
> My whole idea that any option could be viable, as long as
> it does not propose reversed order notation.

Dear Mikhail, so sorry about my misunderstanding, I should read the post
with fewer presuppositions...
Back to the topic, this thread seems to be closed now, and in my opinion
`:=` could be synthetically the best.


2018-04-17 15:11 GMT+08:00 Mikhail V :

> On Tue, Apr 17, 2018 at 6:09 AM, Thautwarm Zhao 
> wrote:
>
> >
> >  > 3) "target ? expr" (where ? is some other word/character -  IIRC
> >  >  "target from expr" was proposed once)
> >
> > A more popular convention is to mark `?` as handling boolean variables,
> so
> > `target ? expr` could mean `expr if target else target`. Other proposal
> for
> > null/boolean checking might need `?`, let's preserve `?` character for
> > further development.
>
> Hey!  I did not propose "?". Read the explanation in parenthesis.
> My whole idea that any option could be viable, as long as
> it does not propose reversed order notation.
>
> But anyway ":=" is better than any keyword imo.
>
>
> Mikhail
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-17 Thread Mikhail V
On Tue, Apr 17, 2018 at 6:09 AM, Thautwarm Zhao  wrote:

>
>  > 3) "target ? expr" (where ? is some other word/character -  IIRC
>  >  "target from expr" was proposed once)
>
> A more popular convention is to mark `?` as handling boolean variables, so
> `target ? expr` could mean `expr if target else target`. Other proposal for
> null/boolean checking might need `?`, let's preserve `?` character for
> further development.

Hey!  I did not propose "?". Read the explanation in parenthesis.
My whole idea that any option could be viable, as long as
it does not propose reversed order notation.

But anyway ":=" is better than any keyword imo.


Mikhail
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Guido van Rossum
On Mon, Apr 16, 2018 at 8:09 PM, Thautwarm Zhao 
wrote:
>
>  > 3) "target ? expr" (where ? is some other word/character -  IIRC
>  >  "target from expr" was proposed once)
>
> A more popular convention is to mark `?` as handling boolean variables, so
> `target ? expr` could mean `expr if target else target`. Other proposal for
> null/boolean checking might need `?`, let's preserve `?` character for
> further development.
>

The only acceptable use of ? is formulated in PEP 505.

-- 
--Guido van Rossum (python.org/~guido)
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Thautwarm Zhao
 > We have ways of cheating a bit if we want to reinterpret the semantics
> of something that nevertheless parses cleanly - while the parser is
> limited to single token lookahead, it's straightforward for the
> subsequent code generation stage to look a single level down in the
> parse tree and see that the code that parsed as "with expr" is
> actually "with subexpr as target".

It does work, however I think it does sound like a patch, and definitely it
will block us to make other extensions in the future.

 > 3) "target ? expr" (where ? is some other word/character -  IIRC
 >  "target from expr" was proposed once)

A more popular convention is to mark `?` as handling boolean variables, so
`target ? expr` could mean `expr if target else target`. Other proposal for
null/boolean checking might need `?`, let's preserve `?` character for
further development.


> How about "name being expression" - this avoids the already used "as"
> while being searchable, reasonably short and gives a reasonably clear,
> (at least to English speakers), indication of what is going on. It can
> also be typed on an ASCII keyboard without having to have a helper
> program or memorising Unicode codes and can be displayed or printed
> without having to install specialised fonts.

It makes sense, if we don't have a long history in Python programming...
A new keyword would be something very dangerous, because it just causes the
crash of some existed library using the keyword as identifier.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Gregory P. Smith
On Mon, Apr 16, 2018 at 11:11 AM Ned Batchelder 
wrote:

> On 4/16/18 1:42 PM, Chris Angelico wrote:
> > 3) "expr -> name" ==> The information went data way.
> >
> > So either you take a parallel from elsewhere in Python syntax, or you
> > take a hopefully-intuitive dataflow mnemonic symbol. Take your pick.
>
> My problem with the "->" option is that function annotations already use
> "->" to indicate the return type of a function.  This is an unfortunate
> parallel from elsewhere in Python syntax, since the meaning is
> completely different.
>
> ":=" is at least new syntax.
>
> "as" is nice in that it's already used for assignment, but seems to be
> causing too much difficulty in parsing, whether by compilers or people.
>
>
FWIW - We used "as" in our Python C++ binding interface description
language in CLIF to denote renaming from the original C++ name to a new
name in Python - effectively an assignment syntax.
   https://github.com/google/clif/blob/master/clif/python/primer.md

I currently have a "-0" opinion on the entire PEP 572 as I don't buy that
assignments within expressions are even a good thing to have in the
language.  #complexity - Think of people learning the language.

-gps
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Chris Angelico
On Tue, Apr 17, 2018 at 5:11 AM, Steve Barnes  wrote:
>
>> Here are the three most popular syntax options, and how each would be 
>> explained:
>>
>> 1) "target := expr" ==> It's exactly the same as other forms of
>> assignment, only now it's an expression.
>> 2) "expr as name" ==> It's exactly the same as other uses of "as",
>> only now it's just grabbing the preceding expression, not actually
>> doing anything with it
>> 3) "expr -> name" ==> The information went data way.
>>
>> So either you take a parallel from elsewhere in Python syntax, or you
>> take a hopefully-intuitive dataflow mnemonic symbol. Take your pick.
>
> How about "name being expression" - this avoids the already used "as"
> while being searchable, reasonably short and gives a reasonably clear,
> (at least to English speakers), indication of what is going on. It can
> also be typed on an ASCII keyboard without having to have a helper
> program or memorising Unicode codes and can be displayed or printed
> without having to install specialised fonts.
>
> If a postfix notation is considered desirable, either instead or as well
> as "being", then possibly another synonym would suit such as "expression
> stored_as name" or "expression storedas name" (not apologies for the
> awkward name as I personally find it an awkward construction just like
> Reverse Polish).

IMO searchability isn't enough of an advantage to justify creating a
new keyword, which could potentially break people's code. (I don't
think it'll break the stdlib, but it'll almost certainly break at
least some code out there.) New keywords have an extremely high bar to
reach.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Ned Batchelder

On 4/16/18 1:42 PM, Chris Angelico wrote:

3) "expr -> name" ==> The information went data way.

So either you take a parallel from elsewhere in Python syntax, or you
take a hopefully-intuitive dataflow mnemonic symbol. Take your pick.


My problem with the "->" option is that function annotations already use 
"->" to indicate the return type of a function.  This is an unfortunate 
parallel from elsewhere in Python syntax, since the meaning is 
completely different.


":=" is at least new syntax.

"as" is nice in that it's already used for assignment, but seems to be 
causing too much difficulty in parsing, whether by compilers or people.


--Ned.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Ethan Furman

On 04/16/2018 10:36 AM, Chris Angelico wrote:


Not after it got trimmed, no. Here's what I actually said in my original post:

while (read_next_item() -> items[i + 1 -> i]) is not None:
 print("%d/%d..." % (i, len(items)), end="\r")

Now, if THAT is your assignment target, are you still as happy as you
had been, or are you assuming that the target is a simple name?


I'm okay with it, although I'd still prefer "as".  But, really, as long as we 
get it* I'll be happy.

--
~Ethan~


* "it" being, of course, assignment-expressions.  :)
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Chris Angelico
On Mon, Apr 16, 2018 at 11:05 PM, Mikhail V  wrote:
> Lets just return to some of proposed examples
> (I use "=" in both examples to be less biased here):
>
> 1.
> if  ( match = re.match("foo", S) ) == True:
> print("match:", match)
>
> 2.
> if  ( re.match("foo", S) = match ) == True:
> print("match:", match)
>
>
> Now seriously, you may argue around those "pronounce"
> theoretical bla bla, like "take the result and save it in a token".
> But the variant 1. is just better, because _it is what it is in Python_.

You start by attempting to be less biased, but you're using existing
Python syntax and then justifying one of the two options because it's
existing Python syntax. I'm not sure that that's a strong argument :)

> So it is better not because it is better looking or whatever,
> it is same sh** turned around. So just don't turn it around!

Obviously if the chosen token is ":=", it's going to be target first.

> When I read code I don't have all those things
> you describe in a millisecond :
> - look at the pointy end of operator
> - think, oh this shows to the right
> - seems like I save the value there
> - yep, that's the way I imply things to work
> - stroking the belly
> 
>
> Instead I just parse visually some smaller parts
> of code and it's just better if the assignment is in the same
> order as everywhere.
> Yes, in some single case one order can look better,
> but in this case it's just not good to mix those.

Here are the three most popular syntax options, and how each would be explained:

1) "target := expr" ==> It's exactly the same as other forms of
assignment, only now it's an expression.
2) "expr as name" ==> It's exactly the same as other uses of "as",
only now it's just grabbing the preceding expression, not actually
doing anything with it
3) "expr -> name" ==> The information went data way.

So either you take a parallel from elsewhere in Python syntax, or you
take a hopefully-intuitive dataflow mnemonic symbol. Take your pick.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Nick Coghlan
On 16 April 2018 at 00:27, Thautwarm Zhao  wrote:
> Personally I prefer "as", but I think without a big change of python Grammar
> file, it's impossible to avoid parsing "with expr as name" into "with (expr
> as name)" because "expr as name" is actually an "expr".
> I have mentioned this in previous discussions and it seems it's better to
> warn you all again. I don't think people of Python-Dev are willing to
> implement a totally new Python compiler.

We have ways of cheating a bit if we want to reinterpret the semantics
of something that nevertheless parses cleanly - while the parser is
limited to single token lookahead, it's straightforward for the
subsequent code generation stage to look a single level down in the
parse tree and see that the code that parsed as "with expr" is
actually "with subexpr as target".

So the main concern around "with (name as expr)" is with human readers
getting confused, not the compiler, as we can tell the latter to
implement whichever semantics we decide we want, while humans are far
less tractable :)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Steven D'Aprano
On Mon, Apr 16, 2018 at 06:16:46AM +1000, Chris Angelico wrote:
[...]

> >> >>> items = [None] * 10
> >> >>> i = -1
> >> >>> items[i := i + 1] = input("> ")
> >> > asdf
> >> >>> items[i := i + 1] = input("> ")
> >> > qwer
> >> >>> items[i := i + 1] = input("> ")
> >> > zxcv
> >> >>>
> >> >>> items
> >> ['asdf', 'qwer', 'zxcv', None, None, None, None, None, None, None]
> >
> >
> > I don't know why you would write that instead of:
> >
> > items = [None]*10
> > for i in range(3):
> > items[i] = input("> ")
> >
> >
> > or even for that matter:
> >
> > items = [input("> ") for i in range(3)] + [None]*7
> >
> >
> > but whatever floats your boat. (Python isn't just not Java. It's also
> > not C *wink*)
> 
> You and Kirill have both fallen into the trap of taking the example
> too far. By completely rewriting it, you destroy its value as an
> example. Write me a better example of a complex target if you like,
> but the question is about how you feel about complex assignment
> targets, NOT how you go about creating a particular list in memory.
> That part is utterly irrelevant.

Chris, I must admit that I'm utterly perplexed at this. Your example is 
as far as from a complex assignment target as you can possibly get. It's 
a simple name! 

i := i + 1

The target is just "i", a name.

The point I was making is that your example is not a good showcase for 
this suggested functionality. Your code violates DRY, repeating the 
exact same line three times. It ought to be put in a loop, and once put 
in a loop, the justification for needing assignment-expression 
disappears.

But having said that, I did respond to your question and swapping the 
order around:

items[i + 1 -> i] = input("> ")

It's still not a "complex target", the target is still just a plain ol' 
name, but it is precisely equivalent to your example.

And then I went further and re-wrote your example to use a genuinely 
complex target, which I won't repeat here.

> >> Are you as happy with that sort of complex
> >> expression coming after 'as' or '->'?
> >
> > Sure. Ignoring the output of the calls to input():
> 
> The calls to input were in a while loop's header for a reason.
> Ignoring them is ignoring the point of assignment expressions.

What while loop? Your example has no while loop.

But regardless, we don't need to care about the *output* (i.e. your 
keypresses echoed to stdout) when looking at the code sample.


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Mikhail V
On Sun, Apr 15, 2018 at 6:58 PM, Steven D'Aprano  wrote:
> On Sun, Apr 15, 2018 at 10:21:02PM +1000, Chris Angelico wrote:
>
>> I don't think we're ever going to unify everyone on an arbitrary
>> question of "expression first" or "name first". But to all the
>> "expression first" people, a question: what if the target is not just
>> a simple name?
>>
>> while (read_next_item() -> items[i + 1 -> i]) is not None:
>> print("%d/%d..." % (i, len(items)), end="\r")
>
> I don't see why it would make a difference. It doesn't to me.
>
>
>> Does this make sense? With the target coming first, it perfectly
>> parallels the existing form of assignment:
>
> Yes, except this isn't ordinary assignment-as-a-statement.
>
> I've been mulling over the question why I think the expression needs to
> come first here, whereas I'm satisfied with the target coming first for
> assignment statements, and I think I've finally got the words to explain
> it. It is not just long familiarity with maths and languages that put
> the variable first (although that's also part of it). It has to do with
> what we're looking for when we read code, specifically what is the
> primary piece of information we're initially looking for.
>
> In assignment STATEMENTS the primary piece of information is the target.
> Yes, of course the value assigned to the target is important, but often
> we don't care what the value is, at least not at first. We're hunting
> for a known target, and only when we find it do we care about the value
> it gets.
>
... [SNIP] 

>
> It is appropriate for assignment statements and expressions to be
> written differently because they are used differently.
>


Wow. That feeling when you see someone giving  reasonable
arguments but in the end comes up with such doubtful conclusions.
So you agree that in general you may need to spot values
and in other case function calls or expressions.
And that's it, its just depends.
So if you swap the order and in some _single_ particular
case you may notice tiny advantage, you conclude that
the whole case with expression assignment needs this order.

Lets just return to some of proposed examples
(I use "=" in both examples to be less biased here):

1.
if  ( match = re.match("foo", S) ) == True:
print("match:", match)

2.
if  ( re.match("foo", S) = match ) == True:
print("match:", match)


Now seriously, you may argue around those "pronounce"
theoretical bla bla, like "take the result and save it in a token".
But the variant 1. is just better, because _it is what it is in Python_.

So it is better not because it is better looking or whatever,
it is same sh** turned around. So just don't turn it around!

Here the 1st variant can be unwrapped to:

match = re.match("foo", S)
if match == True:
print("match:", match)


Do you see what I mean?

When I read code I don't have all those things
you describe in a millisecond :
- look at the pointy end of operator
- think, oh this shows to the right
- seems like I save the value there
- yep, that's the way I imply things to work
- stroking the belly


Instead I just parse visually some smaller parts
of code and it's just better if the assignment is in the same
order as everywhere.
Yes, in some single case one order can look better,
but in this case it's just not good to mix those.



Mikhail
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Kirill Balunov
 [Guido]
2018-04-15 20:19 GMT+03:00 Guido van Rossum :

> On Sun, Apr 15, 2018 at 4:05 AM, Kirill Balunov 
> wrote:
>
>> [...] For me personally, `: =` looks and feels just like normal
>> assignment statement which can be used interchangeable but in many more
>> places in the code. And if the main goal of the PEP was to offer this
>> `assignment expression` as a future replacement for `assignment statement`
>> the `:=` syntax form would be the very reasonable proposal (of course in
>> this case there will be a lot more other questions).
>>
>
> I haven't kept up with what's in the PEP (or much of this thread), but
> this is the key reason I strongly prefer := as inline assignment operator.
>
>
>> But somehow this PEP does not mean it! And with the current rationale of
>> this PEP it's a huge CON for me that `=` and `:=` feel and look the same.
>>
>
> Then maybe the PEP needs to be updated.
>

[Chris]
2018-04-15 23:28 GMT+03:00 Chris Angelico :

> On Mon, Apr 16, 2018 at 3:19 AM, Guido van Rossum 
> wrote:
> > On Sun, Apr 15, 2018 at 4:05 AM, Kirill Balunov  >
> > wrote:
> >> But somehow this PEP does not mean it! And with the current rationale of
> >> this PEP it's a huge CON for me that `=` and `:=` feel and look the
> same.
> >
> > Then maybe the PEP needs to be updated.
>
> I can never be sure what people are reading when they say "current"
> with PEPs like this. The text gets updated fairly frequently. As of
> time of posting, here's the rationale:
>
> -
> Naming the result of an expression is an important part of programming,
> allowing a descriptive name to be used in place of a longer expression,
> and permitting reuse.  Currently, this feature is available only in
> statement form, making it unavailable in list comprehensions and other
> expression contexts.  Merely introducing a way to assign as an expression
> would create bizarre edge cases around comprehensions, though, and to avoid
> the worst of the confusions, we change the definition of comprehensions,
> causing some edge cases to be interpreted differently, but maintaining the
> existing behaviour in the majority of situations.
> -
>
> Kirill, is this what you read, and if so, how does that make ':=' a
> negative? The rationale says "hey, see this really good thing you can
> do as a statement? Let's do it as an expression too", so the parallel
> should be a good thing.
>
>
Yes, this is what I read. I understand why you have such a question so I'll
try to explain my position in more detail. Also I want to add that I did
not fully understand about which part Guido said - "Then maybe the PEP
needs to be updated." Therefore, I allow myself to assume that he had in
mind the following - "The assignment expression should be semantically
equivalent to assignment statement and perceived as a theoretically
possible future replacement (usage) of assignment statement." If this is
really the case and I understood correctly - I will repeat that for me the
current state of the PEP does not fully imply this.

1.  Part - "Then maybe the PEP needs to be updated."

If you really see it as a theoretical substitute for assignment statement
in future Python. I will update the rationale with  maybe the following (I
immediately warn you that I do not pretend to have a good English style):

-
Naming the result of an expression is an important part of programming,
allowing a descriptive name to be used in place of a longer expression,
and permitting reuse.  Currently, in Python this feature is available only
in
statement form, making it unavailable in list comprehensions and other
expression contexts.  This restriction, of making it as a statement, was
done
primarily to avoid the usual trap of `=` vs `==` in C/C++ language.  Despite
this, it is evident that the ability to assign a name within an expression
is convenient, allows to avoid redundant recalculations of the same
expression
and is a familiar feature from other programming languages.  Thus the main
aim
of this PEP is to provide a syntax which will allow to assign as an
expression
and be semantically and visually interchangeable with the assignment
statement.
...
-

In this case, I do not see any reason to discuss the alternative syntax -
there is really only one choice `:=`. And then for me the list of open
questions would look like (for example):
1. ...Is it worth accepting?
2. ...Should the other forms (+=, *=, basically all) that can not be
confused with `==` be changed to expressions?
...


2.  Part - How do I understand the current state of the PEP

I perceive the current rationale as "hey, see this really good thing you
can do as a statement? Let's do it as an expression too".  Which for me
means opportunities to discuss the following questions:
1.  Should assignment expression be viewed as a replacement of an
assignment statement or as a complement to it?
2.  Which spelling should 

Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Kirill Balunov
2018-04-15 23:22 GMT+03:00 Chris Angelico :

>
> > 0.
> >
> > while (items[i := i+1] := read_next_item()) is not None:
> > print(r'%d/%d' % (i, len(items)), end='\r')
> >
> > 1.
> >
> > while (read_next_item() -> items[(i+1) -> i]) is not None:
> > print(r'%d/%d' % (i, len(items)), end='\r')
>
> These two are matching what I wrote, and are thus the two forms under
> consideration. I notice that you added parentheses to the second one;
> is there a clarity problem here and you're unsure whether "i + 1 -> i"
> would capture "i + 1" or "1"? If so, that's a downside to the
> proposal.
>
>
Yes parentheses were used only for clarity. I agree that I misunderstood
the purpose of your question. I have no problem if the right part is a
complex target, but maybe my perception is biased.

With kind regards,
-gdg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Brendan Barnwell

On 2018-04-15 08:58, Steven D'Aprano wrote:

I've been mulling over the question why I think the expression needs to
come first here, whereas I'm satisfied with the target coming first for
assignment statements, and I think I've finally got the words to explain
it. It is not just long familiarity with maths and languages that put
the variable first (although that's also part of it). It has to do with
what we're looking for when we read code, specifically what is the
primary piece of information we're initially looking for.


	Interesting.  I think your arguments are pretty reasonable overall. 
But, for me, they just don't outweigh the fact that "->" is an ugly 
assignment operator that looks nothing like the existing one, whereas 
":=" is a less-ugly one that has the additional benefit of looking like 
the existing one.  From your arguments I am convinced that putting the 
expression first has some advantages, but they just don't seem as 
important to me as they apparently do to you.


--
Brendan Barnwell
"Do not follow where the path may lead.  Go, instead, where there is no 
path, and leave a trail."

   --author unknown
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Chris Angelico
On Mon, Apr 16, 2018 at 4:58 AM, Thautwarm Zhao  wrote:
> Dear Steve, I'm sorry to annoy you by my proposal, but I do think using
> unicode might be wise in current stage.
>
> \triangleq could be print with unicode number \u225c, and adding plugins to
> support typing this in editors could be easy, just simply map \xxx to the
> specific unicode char when we press the tab after typing it.
>
> People using Julia language are proud of it but I think it's just something
> convenient could be used in any other language.
>
> There are other reasons to support unicode but it's out of this topic.
>
> Although ':=' and '->' are not perfect, in the range of ASCII it seems to be
> impossible to find a better one.
>

If you want to introduce non-ASCII tokens to Python, start by adding
them as _alternatives_ to the current syntax. See whether people adopt
them. I've seen one or two people using editors that redisplay
ASCII-only source code using other symbols (eg ≡ for JavaScript's
===), and you could make it so the source code can actually be saved
in that form. But making it so that the ONLY way to use a feature is
to use a non-ASCII character? That's going to break a lot of people's
workflows.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Mikhail V
On Sun, Apr 15, 2018 at 2:01 PM, Nick Coghlan  wrote:
> On 15 April 2018 at 19:41, Mikhail V  wrote:
>> So IIUC, the *only* reason is to avoid '==' ad '=' similarity?
>> If so, then it does not sound convincing at all.
>> Of course Python does me a favor showing an error,
>> when I make a typo like this:
>> if (x = y)
>>
>> But still, if this is the only real reason, it is not convincing.
>
> It's thoroughly convincing, because we're already familiar with the
> consequences of folks confusing "=" and "==" when writing C & C++
> code. It's an eternal bug magnet, so it's not a design we're ever
> going to port over to Python.
[...]
> The examples in the PEP have been updated to better reflect some of
> the key motivating use cases (embedded assignments in if and while
> statement conditions, generator expressions, and container
> comprehensions)

Im personally "0" on the whole proposal. Just was curious
about that "demonisation" of "=" and "==" visual similarity.
Granted, writing ":=" instead of "=" helps a little bit.
But if the ":=" will be accepted, then
we end up with two spellings :-)

>
>> And as a side note: I personally find the look of ":=" a bit 'noisy'.
>
> You're not alone in that, which is one of the reasons finding a
> keyword based option that's less syntactically ambiguous than "as"
> could be an attractive alternative.
>

Keyword variants look less appealing than ":=".
but if it had to be a keyword, then I'd definitely stay by
"TARGET keyword EXPR" just not to swap the traditional order.



Mikhail
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Chris Angelico
On Mon, Apr 16, 2018 at 3:19 AM, Guido van Rossum  wrote:
> On Sun, Apr 15, 2018 at 4:05 AM, Kirill Balunov 
> wrote:
>> But somehow this PEP does not mean it! And with the current rationale of
>> this PEP it's a huge CON for me that `=` and `:=` feel and look the same.
>
> Then maybe the PEP needs to be updated.

I can never be sure what people are reading when they say "current"
with PEPs like this. The text gets updated fairly frequently. As of
time of posting, here's the rationale:

-
Naming the result of an expression is an important part of programming,
allowing a descriptive name to be used in place of a longer expression,
and permitting reuse.  Currently, this feature is available only in
statement form, making it unavailable in list comprehensions and other
expression contexts.  Merely introducing a way to assign as an expression
would create bizarre edge cases around comprehensions, though, and to avoid
the worst of the confusions, we change the definition of comprehensions,
causing some edge cases to be interpreted differently, but maintaining the
existing behaviour in the majority of situations.
-

Kirill, is this what you read, and if so, how does that make ':=' a
negative? The rationale says "hey, see this really good thing you can
do as a statement? Let's do it as an expression too", so the parallel
should be a good thing.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Chris Angelico
On Mon, Apr 16, 2018 at 12:17 AM, Kirill Balunov
 wrote:
>
>
> 2018-04-15 15:21 GMT+03:00 Chris Angelico :
>> I don't think we're ever going to unify everyone on an arbitrary
>> question of "expression first" or "name first". But to all the
>> "expression first" people, a question: what if the target is not just
>> a simple name?
>>
>> while (read_next_item() -> items[i + 1 -> i]) is not None:
>> print("%d/%d..." % (i, len(items)), end="\r")
>>
>
> I completely agree with you that it is impossible to unify everyone opinion
> - we all have different background. But this example is more likely to play
> against this PEP. This is an extra complexity within one line and it can
> fail hard in at least three obvious places :) And I am against this usage no
> matter `name first` or `expression first`. But i will reask this with
> following snippets. What do you choose from this examples:
>
> 0.
>
> while (items[i := i+1] := read_next_item()) is not None:
> print(r'%d/%d' % (i, len(items)), end='\r')
>
> 1.
>
> while (read_next_item() -> items[(i+1) -> i]) is not None:
> print(r'%d/%d' % (i, len(items)), end='\r')

These two are matching what I wrote, and are thus the two forms under
consideration. I notice that you added parentheses to the second one;
is there a clarity problem here and you're unsure whether "i + 1 -> i"
would capture "i + 1" or "1"? If so, that's a downside to the
proposal.

> 2.
>
> while (item := read_next_item()) is not None:
> items[i := (i+1)] = item
> print(r'%d/%d' % (i, len(items)), end='\r')
>
> 3.
>
> while (read_next_item() -> item) is not None:
> items[(i+1) -> i] = item
> print(r'%d/%d' % (i, len(items)), end='\r')
>
> 4.
>
> while (item := read_next_item()) is not None:
> i = i+1
> items[i] = item
> print(r'%d/%d' % (i, len(items)), end='\r')
>
> 5.
>
> while (read_next_item() -> item) is not None:
> i = i+1
> items[i] = item
> print(r'%d/%d' % (i, len(items)), end='\r')

All of these are fundamentally different from what I'm asking: they
are NOT all expressions that can be used in the while header. So it
doesn't answer the question of "expression first" or "target first".
Once the expression gets broken out like this, you're right back to
using "expression -> NAME" or "NAME := expression", and it's the same
sort of simple example that people have been discussing all along.

> I am definitely Ok with both 2 and 3 here. But as it was noted `:=` produces
> additional noise in other places and I am also an `expression first` guy :)
> So I still prefer variant 3 to 2. But to be completely honest, I would write
> it in the following way:
>
> for item in iter(read_next_item, None):
> items.append(item)
> print(r'%d/%d' % (i, len(items)), end='\r')

And that's semantically different in several ways. Not exactly a fair
comparison.

I invite you to write up a better example with a complex target.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Chris Angelico
On Mon, Apr 16, 2018 at 1:58 AM, Steven D'Aprano  wrote:
> On Sun, Apr 15, 2018 at 10:21:02PM +1000, Chris Angelico wrote:
>
>> I don't think we're ever going to unify everyone on an arbitrary
>> question of "expression first" or "name first". But to all the
>> "expression first" people, a question: what if the target is not just
>> a simple name?
>>
>> while (read_next_item() -> items[i + 1 -> i]) is not None:
>> print("%d/%d..." % (i, len(items)), end="\r")
>
> I don't see why it would make a difference. It doesn't to me.

Okay, that's good. I just hear people saying "name" a lot, but that
would imply restricting the grammar to just a name, and I don't know
how comfortable people are with more complex targets.

>> Does this make sense? With the target coming first, it perfectly
>> parallels the existing form of assignment:
>
> Yes, except this isn't ordinary assignment-as-a-statement.
>
> I've been mulling over the question why I think the expression needs to
> come first here, whereas I'm satisfied with the target coming first for
> assignment statements, and I think I've finally got the words to explain
> it. It is not just long familiarity with maths and languages that put
> the variable first (although that's also part of it). It has to do with
> what we're looking for when we read code, specifically what is the
> primary piece of information we're initially looking for.
>
> In assignment STATEMENTS the primary piece of information is the target.
> Yes, of course the value assigned to the target is important, but often
> we don't care what the value is, at least not at first. We're hunting
> for a known target, and only when we find it do we care about the value
> it gets.
> [chomp details]

> It is appropriate for assignment statements and expressions to be
> written differently because they are used differently.

I don't know that assignment expressions are inherently going to be
used in ways where you ignore the assignment part and care only about
the expression part. And I disagree that assignment statements are
used primarily the way you say. Frequently I skim down a column of
assignments, caring primarily about the functions being called, and
looking at the part before the equals sign only when I come across a
parameter in another call; the important part of the line is what it's
doing, not where it's stashing its result.

> [...]
>> >>> items = [None] * 10
>> >>> i = -1
>> >>> items[i := i + 1] = input("> ")
>> > asdf
>> >>> items[i := i + 1] = input("> ")
>> > qwer
>> >>> items[i := i + 1] = input("> ")
>> > zxcv
>> >>>
>> >>> items
>> ['asdf', 'qwer', 'zxcv', None, None, None, None, None, None, None]
>
>
> I don't know why you would write that instead of:
>
> items = [None]*10
> for i in range(3):
> items[i] = input("> ")
>
>
> or even for that matter:
>
> items = [input("> ") for i in range(3)] + [None]*7
>
>
> but whatever floats your boat. (Python isn't just not Java. It's also
> not C *wink*)

You and Kirill have both fallen into the trap of taking the example
too far. By completely rewriting it, you destroy its value as an
example. Write me a better example of a complex target if you like,
but the question is about how you feel about complex assignment
targets, NOT how you go about creating a particular list in memory.
That part is utterly irrelevant.

>> Are you as happy with that sort of complex
>> expression coming after 'as' or '->'?
>
> Sure. Ignoring the output of the calls to input():

The calls to input were in a while loop's header for a reason.
Ignoring them is ignoring the point of assignment expressions.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Kirill Balunov
2018-04-15 18:58 GMT+03:00 Steven D'Aprano :

>
> [...]
>
> But this time we don't care about the name. Its the value we care about:
>
> result = some_func(don't care,
>don't care -> don't care
>don't care -> don't care
>don't care(don't care),
>HERE IT IS  ,
>...)
>

This made my day! :) The programming style when you absolutely don't care
:))) I understand that this is a typo but it turned out to be very funny.

In general, I agree with everything you've said. And I think you found a
very correct way to explain why expression should go first in assignment
expression.

With kind regards,
-gdg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Steven D'Aprano
On Sun, Apr 15, 2018 at 11:11:37PM +0800, Thautwarm Zhao wrote:

> I think maybe we can use unicode characters like ≜ (\triangleq) and add the
> support of unicode completion to python repl. The unicode completion of
> editors or ides has been quite mature.

What key combination do I need to type to get ≜ in the following editors 
please? I tried typing \triangleq but all I got was \triangleq.

Notepad (Windows)
Brackets (Mac)
BBEdit (Mac)
kwrite (Linux)
kate
nano
geany
gedit

as well as IDLE, my mail client (kmail, Thunderbird or mutt), my web 
browsers (Firefox, Opera and Chromium), the interactive interpreter in 
various different consoles, my Usenet client (Pan and KNode) and IRC 
(pidgin).

Oh, having it work in LibreOffice and GoogleApps too would be nice, 
although not essential since I don't often write code in them.

And what decent fonts do I need to install for ≜ to show up as something 
other than a square box ("missing glyph")?


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Steven D'Aprano
On Sun, Apr 15, 2018 at 10:21:02PM +1000, Chris Angelico wrote:

> I don't think we're ever going to unify everyone on an arbitrary
> question of "expression first" or "name first". But to all the
> "expression first" people, a question: what if the target is not just
> a simple name?
> 
> while (read_next_item() -> items[i + 1 -> i]) is not None:
> print("%d/%d..." % (i, len(items)), end="\r")

I don't see why it would make a difference. It doesn't to me.


> Does this make sense? With the target coming first, it perfectly
> parallels the existing form of assignment:

Yes, except this isn't ordinary assignment-as-a-statement.

I've been mulling over the question why I think the expression needs to 
come first here, whereas I'm satisfied with the target coming first for 
assignment statements, and I think I've finally got the words to explain 
it. It is not just long familiarity with maths and languages that put 
the variable first (although that's also part of it). It has to do with 
what we're looking for when we read code, specifically what is the 
primary piece of information we're initially looking for.

In assignment STATEMENTS the primary piece of information is the target. 
Yes, of course the value assigned to the target is important, but often 
we don't care what the value is, at least not at first. We're hunting 
for a known target, and only when we find it do we care about the value 
it gets.

A typical scenario: I'm reading a function, and I scan down the block 
looking at the start of each line until I find the variable I want:

spam = don't care
eggs = don't care
self.method(don't care)
cheese = ... <<< HERE IT IS

so it actually helps to have the name up front. Copying standard maths 
notation for assignment (variable first, value second) is a good thing 
for statements.

With assignment-statements, if you're scanning the code for a variable 
name, you're necessarily interested in the name and it will be helpful 
to have it on the left.

But with assignment-expressions, there's an additional circumstance: 
sometimes you don't care about the name, you only care what the value 
is. (I expect this will be more common.) The name is just something 
to skip over when you're scanning the code looking for the value.

# what did I pass as the fifth argument to the function?
result = some_func(don't care, spam := don't care, eggs := don't care,
   self.method(don't care), cheese := HERE IT IS, 
   ...)

Of course it's hard counting commas so it's probably better to add a bit 
of structure to your function call:

result = some_func(don't care, 
   spam := don't care, 
   eggs := don't care,
   self.method(don't care), 
   cheese := HERE IT IS, 
   ...)


But this time we don't care about the name. Its the value we care about:

result = some_func(don't care, 
   don't care -> don't care
   don't care -> don't care
   don't care(don't care), 
   HERE IT IS  ,
   ...)


The target is just one more thing you have to ignore, and it is helpful 
to have expression first and the target second.

Some more examples:

# what am I adding to the total?
total += don't care := expression

# what key am I looking up?
print(mapping[don't care := key])

# how many items did I just skip?
self.skip(don't care := obj.start + extra)


versus

total += expression -> don't care
print(mapping[key -> don't care])
self.skip(obj.start + extra -> don't care)


It is appropriate for assignment statements and expressions to be 
written differently because they are used differently.



[...]
> >>> items = [None] * 10
> >>> i = -1
> >>> items[i := i + 1] = input("> ")
> > asdf
> >>> items[i := i + 1] = input("> ")
> > qwer
> >>> items[i := i + 1] = input("> ")
> > zxcv
> >>>
> >>> items
> ['asdf', 'qwer', 'zxcv', None, None, None, None, None, None, None]


I don't know why you would write that instead of:

items = [None]*10
for i in range(3):
items[i] = input("> ")


or even for that matter:

items = [input("> ") for i in range(3)] + [None]*7


but whatever floats your boat. (Python isn't just not Java. It's also 
not C *wink*)


> Are you as happy with that sort of complex
> expression coming after 'as' or '->'?

Sure. Ignoring the output of the calls to input():

items = [None] * 10
i = -1
items[i + 1 -> i] = input("> ")
items[i + 1 -> i] = input("> ")
items[i + 1 -> i] = input("> ")


which isn't really such a complex target. How about this instead?


obj = SimpleNamespace(spam=None, eggs=None, 
  aardvark={'key': [None, None, -1]}
  )
items[obj.aardvark['key'][2] + 1 -> obj.aardvark['key'][2]] = input("> ")

versus:

items[obj.aardvark['key'][2] := obj.aardvark['key'][2] + 

Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Thautwarm Zhao
>
>
> 0.
>
> while (items[i := i+1] := read_next_item()) is not None:
> print(r'%d/%d' % (i, len(items)), end='\r')
>
> 1.
>
> while (read_next_item() -> items[(i+1) -> i]) is not None:
> print(r'%d/%d' % (i, len(items)), end='\r')
>
> 2.
>
> while (item := read_next_item()) is not None:
> items[i := (i+1)] = item
> print(r'%d/%d' % (i, len(items)), end='\r')
>
> 3.
>
> while (read_next_item() -> item) is not None:
> items[(i+1) -> i] = item
> print(r'%d/%d' % (i, len(items)), end='\r')
>
> 4.
>
> while (item := read_next_item()) is not None:
> i = i+1
> items[i] = item
> print(r'%d/%d' % (i, len(items)), end='\r')
>
> 5.
>
> while (read_next_item() -> item) is not None:
> i = i+1
> items[i] = item
> print(r'%d/%d' % (i, len(items)), end='\r')
>
>
Also 2 or 3.
The 3rd one is in the order of natural language, just like:
while get then next item and assign it to `item`, if it's not None, do
some stuff.

However just as we have pointed out, the semantics of '->' is quite
different from the cases it's currently used at, so it should be handled
much more carefully.

I think maybe we can use unicode characters like ≜ (\triangleq) and add the
support of unicode completion to python repl. The unicode completion of
editors or ides has been quite mature.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Thautwarm Zhao
> To me, "from" strongly suggests that an element is being obtained from a
container/collection of
> elements. This is how I conceptualize "from module import name": "name"
refers to an object
> INSIDE the module, not the module itself. If I saw
>
> if (match from pattern.search(data)) is not None:
...

> I would guess that it is equivalent to
>
> m = next(pattern.search(data))
> if m is not None:
...

+1, although unpacking seems to be reasonable `[elem1, *elems] from
contains`.


Now we have

- "expr as name"
- "name := expr"
- "expr -> name"
- "name from expr"

Personally I prefer "as", but I think without a big change of python
Grammar file, it's impossible to avoid parsing "with expr as name" into
"with (expr as name)" because "expr as name" is actually an "expr".
I have mentioned this in previous discussions and it seems it's better to
warn you all again. I don't think people of Python-Dev are willing to
implement a totally new Python compiler.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Kirill Balunov
2018-04-15 15:21 GMT+03:00 Chris Angelico :

> On Sun, Apr 15, 2018 at 7:19 PM, Kirill Balunov 
> wrote:
> >> === Expression first, 'as' keyword ===
> >>
> >> while (read_next_item() as value) is not None:
> >> ...
> >>
> >> Pros:
> >>
> >>   * typically reads nicely as pseudocode
> >>   * "as" is already associated with namebinding operations
> >>
> >
> > I understand that this list is subjective. But as for me it will be huge
> PRO
> > that the expression comes first.
>
> I don't think we're ever going to unify everyone on an arbitrary
> question of "expression first" or "name first". But to all the
> "expression first" people, a question: what if the target is not just
> a simple name?
>
> while (read_next_item() -> items[i + 1 -> i]) is not None:
> print("%d/%d..." % (i, len(items)), end="\r")
>
> [...]
>
> Not a rhetorical question. I'm genuinely curious as to whether people
> are expecting "expression -> NAME" or "expression -> TARGET", where
> TARGET can be any valid assignment target.
>
>
I completely agree with you that it is impossible to unify everyone opinion
- we all have different background. But this example is more likely to play
against this PEP. This is an extra complexity within one line and it can
fail hard in at least three obvious places :) And I am against this usage
no matter `name first` or `expression first`. But i will reask this with
following snippets. What do you choose from this examples:

0.

while (items[i := i+1] := read_next_item()) is not None:
print(r'%d/%d' % (i, len(items)), end='\r')

1.

while (read_next_item() -> items[(i+1) -> i]) is not None:
print(r'%d/%d' % (i, len(items)), end='\r')

2.

while (item := read_next_item()) is not None:
items[i := (i+1)] = item
print(r'%d/%d' % (i, len(items)), end='\r')

3.

while (read_next_item() -> item) is not None:
items[(i+1) -> i] = item
print(r'%d/%d' % (i, len(items)), end='\r')

4.

while (item := read_next_item()) is not None:
i = i+1
items[i] = item
print(r'%d/%d' % (i, len(items)), end='\r')

5.

while (read_next_item() -> item) is not None:
i = i+1
items[i] = item
print(r'%d/%d' % (i, len(items)), end='\r')

I am definitely Ok with both 2 and 3 here. But as it was noted `:=`
produces additional noise in other places and I am also an `expression
first` guy :) So I still prefer variant 3 to 2. But to be completely
honest, I would write it in the following way:

for item in iter(read_next_item, None):
items.append(item)
print(r'%d/%d' % (i, len(items)), end='\r')


With kind regards,
-gdg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Chris Angelico
On Sun, Apr 15, 2018 at 7:19 PM, Kirill Balunov  wrote:
>> === Expression first, 'as' keyword ===
>>
>> while (read_next_item() as value) is not None:
>> ...
>>
>> Pros:
>>
>>   * typically reads nicely as pseudocode
>>   * "as" is already associated with namebinding operations
>>
>
> I understand that this list is subjective. But as for me it will be huge PRO
> that the expression comes first.

I don't think we're ever going to unify everyone on an arbitrary
question of "expression first" or "name first". But to all the
"expression first" people, a question: what if the target is not just
a simple name?

while (read_next_item() -> items[i + 1 -> i]) is not None:
print("%d/%d..." % (i, len(items)), end="\r")

Does this make sense? With the target coming first, it perfectly
parallels the existing form of assignment:

>>> items = [None] * 10
>>> i = -1
>>> i, items[i] = i+1, input("> ")
> asdf
>>> i, items[i] = i+1, input("> ")
> qwer
>>> i, items[i] = i+1, input("> ")
> zxcv
>>> items
['asdf', 'qwer', 'zxcv', None, None, None, None, None, None, None]

The unpacking syntax is a bit messy, but with expression assignment,
we can do this:

>>> items = [None] * 10
>>> i = -1
>>> items[i := i + 1] = input("> ")
> asdf
>>> items[i := i + 1] = input("> ")
> qwer
>>> items[i := i + 1] = input("> ")
> zxcv
>>>
>>> items
['asdf', 'qwer', 'zxcv', None, None, None, None, None, None, None]

Okay, it's not quite as simple as C's "items[i++]" (since you have to
start i off at negative one so you can pre-increment), but it's still
logical and sane. Are you as happy with that sort of complex
expression coming after 'as' or '->'?

Not a rhetorical question. I'm genuinely curious as to whether people
are expecting "expression -> NAME" or "expression -> TARGET", where
TARGET can be any valid assignment target.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Kirill Balunov
2018-04-15 12:41 GMT+03:00 Mikhail V :

>
> Exactly, all forms invites this and other questions.
>
> First of all, coming back to original spelling choice arguments
> [Sorry in advance if I've missed some points in this huge thread]
>
> citation from PEP:
>   "Differences from regular assignment statements" [...]
>   "Otherwise, the semantics of assignment are unchanged by this proposal."
>
> So basically it's the same Python assignment?
> Then obvious solution seems just to propose "=".
> But I see Chris have put this in FAQ section:
> "The syntactic similarity between ``if (x == y)`` and ``if (x = y)`` "
>

[OT] To be honest I never liked the fact that `=` was used in various
programming languages as assignment. But it became so common that and I got
used to it and even stopped taking a sedative :)

So IIUC, the *only* reason is to avoid '==' ad '=' similarity?
> If so, then it does not sound convincing at all.
> Of course Python does me a favor showing an error,
> when I make a typo like this:
> if (x = y)
>
> But still, if this is the only real reason, it is not convincing.
> Syntactically seen, I feel strong that normal '=' would be the way to go.
>
> Just look at this:
> y = ((eggs := spam()), (cheese := eggs.method())
> y = ((eggs = spam()), (cheese = eggs.method())
>
> The latter is so much cleaner, and already so common to any
> old or new Python user. And does not raise a
> question what this ":=" should really mean.
> (Or probably it should raise such question?)
>
> Given the fact that the PEP gives quite edge-case
> usage examples only, this should be really more convincing.
> And as a side note: I personally find the look of ":=" a bit 'noisy'.
>

You are not alone. On the other hand it is one of the strengths of Python -
not allow to do so common and complex to finding bugs. For me personally,
`: =` looks and feels just like normal assignment statement which can be
used interchangeable but in many more places in the code. And if the main
goal of the PEP was to offer this `assignment expression` as a future
replacement for `assignment statement` the `:=` syntax form would be the
very reasonable proposal (of course in this case there will be a lot more
other questions). But somehow this PEP does not mean it! And with the
current rationale of this PEP it's a huge CON for me that `=` and `:=` feel
and look the same.


>
> Another point:
>
> *Target first  vs  Expression first*
> ===
>
> Well, this is nice indeed. Don't you find that first of all it must be
> decided what should be the *overall tendency for Python*?
> Now we have common "x = a + b" everywhere. Then there
> are comprehensions (somewhat mixed direction) and
> "foo as bar" things.
> But wait, is the tendency to "give the freedom"? Then you should
> introduce something like "<--" in the first place so that we can
> write normal assignment in both directions.
>

As it was noted previously `<-` would not work because of unary minus on
the right:

>>> x = 10
>>> x <- 5
False



> Or is the tendency to convert Python to the "expression first" generally?
>
> So if this question can be answered first, then I think it will be
> more constructive to discuss the choice of particular spellings.
>

If the idea of the whole PEP was to replace `assignment statement` with
`assignment expression` I would choose name first. If the idea was to offer
an expression with the name-binding side effect, which can be used in the
appropriate places I would choose expression first.

With kind regards,
-gdg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Nick Coghlan
On 15 April 2018 at 19:41, Mikhail V  wrote:
> So IIUC, the *only* reason is to avoid '==' ad '=' similarity?
> If so, then it does not sound convincing at all.
> Of course Python does me a favor showing an error,
> when I make a typo like this:
> if (x = y)
>
> But still, if this is the only real reason, it is not convincing.

It's thoroughly convincing, because we're already familiar with the
consequences of folks confusing "=" and "==" when writing C & C++
code. It's an eternal bug magnet, so it's not a design we're ever
going to port over to Python. (And that's even before we get into the
parsing ambiguity problems that attempting to reuse "=" for this
purpose in Python would introduce, especially when it comes to keyword
arguments).

The only way Python will ever gain expression level name binding
support is with a spelling *other than* "=", as when that's the
proposed spelling, the answer will be an unequivocal "No, we're not
adding that".

Even if the current discussion does come up with a potentially
plausible spelling, the final determination on python-dev may *still*
be "No, we're not going to add that". That isn't a predetermined
answer though - it will depend on whether or not a proposal can be
developed that threads the small gap between "this adds too much new
cognitive overhead to reading and writing the language" and "while
this does add more complexity to the base language, it provides
sufficient compensation in allowing common ideas to be expressed more
simply".

> Syntactically seen, I feel strong that normal '=' would be the way to go.
>
> Just look at this:
> y = ((eggs := spam()), (cheese := eggs.method())
> y = ((eggs = spam()), (cheese = eggs.method())
>
> The latter is so much cleaner, and already so common to any
> old or new Python user.

Consider how close the second syntax is to "y = f(eggs=spam(),
cheese=fromage())", though.


> Given the fact that the PEP gives quite edge-case
> usage examples only, this should be really more convincing.

The examples in the PEP have been updated to better reflect some of
the key motivating use cases (embedded assignments in if and while
statement conditions, generator expressions, and container
comprehensions)

> And as a side note: I personally find the look of ":=" a bit 'noisy'.

You're not alone in that, which is one of the reasons finding a
keyword based option that's less syntactically ambiguous than "as"
could be an attractive alternative.

> Another point:
>
> *Target first  vs  Expression first*
> ===
>
> Well, this is nice indeed. Don't you find that first of all it must be
> decided what should be the *overall tendency for Python*?
> Now we have common "x = a + b" everywhere. Then there
> are comprehensions (somewhat mixed direction) and
> "foo as bar" things.
> But wait, is the tendency to "give the freedom"? Then you should
> introduce something like "<--" in the first place so that we can
> write normal assignment in both directions.
> Or is the tendency to convert Python to the "expression first" generally?

There's no general tendency towards expression first syntax, nor
towards offering flexibility in whether ordinary assignments are
target first.

All the current cases where we use the "something as target" form are
*not* direct equivalents to "target = something":

* "import dotted.modname as name": also prevents "dotted" getting
bound in the current scope the way it normally would
* "from dotted import modname as name": also prevents "modname"
getting bound in the current scope the way it normally would
* "except exc_filter as exc": binds the caught exception, not the
exception filter
* "with cm as name": binds the result of __enter__ (which may be
self), not the cm directly

Indeed, https://www.python.org/dev/peps/pep-0343/#motivation-and-summary
points out that it's this "not an ordinary assignment" aspect that
lead to with statements using the "with cm as name:" structure in the
first place - the original proposal in PEP 310 was for "with name =
cm:" and ordinary assignment semantics.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Mikhail V
On Sun, Apr 15, 2018 at 12:19 PM, Kirill Balunov
 wrote:
>
>
> 2018-04-15 6:08 GMT+03:00 Nick Coghlan :
>>
>>

>
>>
>> P.S. The pros and cons of the current syntax proposals, as I see them:
>>
>> === Expression first, 'as' keyword ===
>>
>> while (read_next_item() as value) is not None:
>> ...
>>
>> Pros:
>>
>>   * typically reads nicely as pseudocode
>>   * "as" is already associated with namebinding operations
>>
>
> I understand that this list is subjective. But as for me it will be huge PRO
> that the expression comes first.
>
[...]
>>
>> === Expression first, '->' symbol ===
>>
>> while (read_next_item() -> value) is not None:
>> ...
>>
>> Pros:
>>
>>   * avoids the syntactic ambiguity of "as"
>>   * "->" is used for name bindings in at least some other languages
>> (but this is irrelevant to users for whom Python is their first, and
>> perhaps only, programming language)
[...]
>
>>
>>   * invites the question "Why doesn't this use the 'as' keyword?"
>
>
> All forms invites this question :)))


Exactly, all forms invites this and other questions.

First of all, coming back to original spelling choice arguments
[Sorry in advance if I've missed some points in this huge thread]

citation from PEP:
  "Differences from regular assignment statements" [...]
  "Otherwise, the semantics of assignment are unchanged by this proposal."

So basically it's the same Python assignment?
Then obvious solution seems just to propose "=".
But I see Chris have put this in FAQ section:
"The syntactic similarity between ``if (x == y)`` and ``if (x = y)`` "

So IIUC, the *only* reason is to avoid '==' ad '=' similarity?
If so, then it does not sound convincing at all.
Of course Python does me a favor showing an error,
when I make a typo like this:
if (x = y)

But still, if this is the only real reason, it is not convincing.
Syntactically seen, I feel strong that normal '=' would be the way to go.

Just look at this:
y = ((eggs := spam()), (cheese := eggs.method())
y = ((eggs = spam()), (cheese = eggs.method())

The latter is so much cleaner, and already so common to any
old or new Python user. And does not raise a
question what this ":=" should really mean.
(Or probably it should raise such question?)

Given the fact that the PEP gives quite edge-case
usage examples only, this should be really more convincing.
And as a side note: I personally find the look of ":=" a bit 'noisy'.


Another point:

*Target first  vs  Expression first*
===

Well, this is nice indeed. Don't you find that first of all it must be
decided what should be the *overall tendency for Python*?
Now we have common "x = a + b" everywhere. Then there
are comprehensions (somewhat mixed direction) and
"foo as bar" things.
But wait, is the tendency to "give the freedom"? Then you should
introduce something like "<--" in the first place so that we can
write normal assignment in both directions.
Or is the tendency to convert Python to the "expression first" generally?

So if this question can be answered first, then I think it will be
more constructive to discuss the choice of particular spellings.



Mikhail
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Kirill Balunov
2018-04-15 6:08 GMT+03:00 Nick Coghlan :

>
> It's not completely off topic. as it's due to the fact we use "," to
> separate both context managers and items in a tuple, so "with (cm1,
> cm2, cm3):" is currently legal syntax that means something quite
> different from "with cm1, cm2, cm3:". While using the parenthesised
> form is *pointless* (since it will blow up at runtime due to tuples
> not being context managers), the fact it's syntactically valid makes
> us more hesitant to add the special case around parentheses handling
> than we were for import statements. The relevance to PEP 572 is as a
> reminder that since we *really* don't like to add yet more different
> cases to "What do parentheses indicate in Python?"


Despite the fact that "with (cm1,cm2, cm3):"  currently is the legal
syntax, but as you said and as it was also noted before in this thread - it
is "pointless" in 99% cases (in context of with statement) and will fail at
runtime. Therefore, regardless of this PEP, maybe it is fair to make it at
least to be a `SyntaxWarning` (or `SyntaxError`)? Better fail sooner than
later.


we should probably
> show similar hesitation when it comes to giving ":" yet another
> meaning.
>
>
Yes, `:` is used (as a symbol) in a lot of places (in fact there is not
much in it), but in some places Python looks as a combination of words and
colons.


> P.S. The pros and cons of the current syntax proposals, as I see them:
>
> === Expression first, 'as' keyword ===
>
> while (read_next_item() as value) is not None:
> ...
>
> Pros:
>
>   * typically reads nicely as pseudocode
>   * "as" is already associated with namebinding operations
>
>
I understand that this list is subjective. But as for me it will be huge
PRO that the expression comes first.


> Cons:
>
>   * syntactic ambiguity in with statement headers (major concern)
>   * encourages a common misunderstanding of how with statements work
> (major concern)
>   * visual similarity between "as" and "and" makes name bindings easy to
> miss
>   * syntactic ambiguity in except clause headers theoretically exists,
> but is less of a concern due to the consistent type difference that
> makes the parenthesised form pointless
>
>
In reality, the first two points can be explained (if it will be required
at all). Misunderstanding is a consequence of a lack of experience. I don't
understand the the point about "visual similarity between "as" and "and"
can you elaborate on this point a little bit more?



> === Expression first, '->' symbol ===
>
> while (read_next_item() -> value) is not None:
> ...
>
> Pros:
>
>   * avoids the syntactic ambiguity of "as"
>   * "->" is used for name bindings in at least some other languages
> (but this is irrelevant to users for whom Python is their first, and
> perhaps only, programming language)
>
>
The same as previous,  the expression comes first is a huge PRO for me and
I'm sure for many others too. With the second point I agree that it is
somewhat irrelevant.


> Cons:
>
>   * doesn't read like pseudocode (you need to interpret an arbitrary
> non-arithmetic symbol)
>

Here I am a bit disagree with you. The most common for of assignment in
formal pseudo-code is `name <- expr`. The second most common form, to my
regret,  is - `:=`. The `<-` form is not possible in Python and that is why
`expr -> name` was suggested.


>   * invites the question "Why doesn't this use the 'as' keyword?"
>

All forms invites this question :)))


>   * symbols are typically harder to look up than keywords
>   * symbols don't lend themselves to easy mnemonics
>   * somewhat arbitrary repurposing of "->" compared to its use in
> function annotations
>
>  The last one is a major concern. I think that is why Guido is so
skeptical about this form.


> === Target first, ':=' symbol ===
>
> while (value := read_next_item()) is not None:
> ...
>
> Pros:
>
>   * avoids the syntactic ambiguity of "as"
>   * being target first provides an obvious distinction from the "as"
> keyword
>

For me it is a CON. Originally the rationale of this PEP was to reduce the
number of unnecessary calculations and to provide a useful syntax to make a
name binding in appropriate places. It should not, in any way, replace the
existing `=` usual way to make a name binding. Therefore, as I see it, it
is one of design goals to make the syntax forms of `assignment statement`
and `assignment expression` to be distinct and `:=` does not help with
this. This does not mean that this new syntax form should not be
convenient, but it should be different from the usual `=` form.


>   * ":=" is used for name bindings in at least some other languages
> (but this is irrelevant to users for whom Python is their first, and
> perhaps only, language)
>
> Cons:
>
>   * symbols are typically harder to look up than keywords
>   * symbols don't lend themselves to easy mnemonics
>   * subject to a visual "line noise" phenomenon when combined with
> 

Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Nick Coghlan
On 15 April 2018 at 13:54, Chris Angelico  wrote:
> On Sun, Apr 15, 2018 at 1:08 PM, Nick Coghlan  wrote:
>> === Target first, 'from' keyword ===
>>
>> while (value from read_next_item()) is not None: # New
>> ...
>>
>> Pros:
>>
>>   * avoids the syntactic ambiguity of "as"
>>   * being target first provides an obvious distinction from the "as" keyword
>>   * typically reads nicely as pseudocode
>>   * "from" is already associated with a namebinding operation ("from
>> module import name")
>>
>> Cons:
>>
>>   * I'm sure we'll think of some more, but all I have so far is that
>> the association with name binding is relatively weak and would need to
>> be learned
>>
>
> Cons: Syntactic ambiguity with "raise exc from otherexc", probably not 
> serious.

Ah, I forgot about that usage. The keyword usage is at least somewhat
consistent, in that it's short for:

_tmp = exc
_exc.__cause__ from otherexc
raise exc

However, someone writing "raise (ExcType from otherexc)" could be
confusing, since it would end up re-raising "otherexc" instead of
wrapping it in a new ExcType instance. If "otherexc" was also an
ExcType instance, that would be a *really* subtle bug to try and
catch, so this would likely need the same kind of special casing as
was proposed for "as" (i.e. prohibiting the top level parentheses).

I also agree with Nathan that if you hadn't encountered from
expressions before, it would be reasonable to assume they were
semantically comparable to "target = next(expr)" rather than just
"target = expr".

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Nathan Schneider
On Sat, Apr 14, 2018 at 11:54 PM, Chris Angelico  wrote:

> On Sun, Apr 15, 2018 at 1:08 PM, Nick Coghlan  wrote:
> > === Target first, 'from' keyword ===
> >
> > while (value from read_next_item()) is not None: # New
> > ...
> >
> > Pros:
> >
> >   * avoids the syntactic ambiguity of "as"
> >   * being target first provides an obvious distinction from the "as"
> keyword
> >   * typically reads nicely as pseudocode
> >   * "from" is already associated with a namebinding operation ("from
> > module import name")
> >
> > Cons:
> >
> >   * I'm sure we'll think of some more, but all I have so far is that
> > the association with name binding is relatively weak and would need to
> > be learned
> >
>
> Cons: Syntactic ambiguity with "raise exc from otherexc", probably not
> serious.
>
>
To me, "from" strongly suggests that an element is being obtained from a
container/collection of elements. This is how I conceptualize "from module
import name": "name" refers to an object INSIDE the module, not the module
itself. If I saw

if (match from pattern.search(data)) is not None:
...

I would guess that it is equivalent to

m = next(pattern.search(data))
if m is not None:
...

i.e. that the target is bound to the next item from an iterable (the
"container").

Cheers,
Nathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-14 Thread Ethan Furman

On 04/14/2018 08:08 PM, Nick Coghlan wrote:


New keyword based target first proposal:

 while (value from read_next_item()) is not None:
 ...


I could get behind this.

Current preferencs:

"as"  +1

"from"  +0.85

":=" +0.5

--
~Ethan~

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-14 Thread Chris Angelico
On Sun, Apr 15, 2018 at 1:08 PM, Nick Coghlan  wrote:
> === Target first, 'from' keyword ===
>
> while (value from read_next_item()) is not None: # New
> ...
>
> Pros:
>
>   * avoids the syntactic ambiguity of "as"
>   * being target first provides an obvious distinction from the "as" keyword
>   * typically reads nicely as pseudocode
>   * "from" is already associated with a namebinding operation ("from
> module import name")
>
> Cons:
>
>   * I'm sure we'll think of some more, but all I have so far is that
> the association with name binding is relatively weak and would need to
> be learned
>

Cons: Syntactic ambiguity with "raise exc from otherexc", probably not serious.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-14 Thread Nick Coghlan
On 13 April 2018 at 23:18, Steven D'Aprano  wrote:
> On Fri, Apr 13, 2018 at 09:56:35PM +1000, Chris Angelico wrote:
>
>
>> How many times have people asked for "with (expr as name):" to
>> be supported, allowing the statement to spread over multiple lines?
>> With this syntax, it would suddenly be permitted - with dangerously
>> similar semantics.
>
> I see your point, but why don't we support "with (expr as name):" to
> allow multiple lines? No, don't answer that... its off-topic. Forget I
> asked.

It's not completely off topic. as it's due to the fact we use "," to
separate both context managers and items in a tuple, so "with (cm1,
cm2, cm3):" is currently legal syntax that means something quite
different from "with cm1, cm2, cm3:". While using the parenthesised
form is *pointless* (since it will blow up at runtime due to tuples
not being context managers), the fact it's syntactically valid makes
us more hesitant to add the special case around parentheses handling
than we were for import statements. The relevance to PEP 572 is as a
reminder that since we *really* don't like to add yet more different
cases to "What do parentheses indicate in Python?", we should probably
show similar hesitation when it comes to giving ":" yet another
meaning.

This morning, I remembered a syntax idea I had a while back in
relation to lambda expressions that could perhaps be better applied to
assignment expressions, so I'll quickly recap the current options, and
then go on to discussing that. Since the threads are pretty sprawling,
I've also included a postscript going into more detail on my current
view of the pros and cons of the various syntax proposals presented so
far.

Expression first proposals:

while (read_next_item() as value) is not None:
...

while (read_next_item() -> value) is not None:
...

Target first proposal (current PEP):

while (value := read_next_item()) is not None:
...

New keyword based target first proposal:

while (value from read_next_item()) is not None:
...

The new one is a fairly arbitrary repurposing of the import system's
"from" keyword, but it avoids all the ambiguities of "as", is easier
to visually distinguish from other existing expression level keywords
than "as", avoids giving ":" yet another meaning, still lets us use a
keyword instead of a symbol, and gives the new expression type a more
clearly self-evident name ("from expressions", as opposed to the "from
statements" used for imports).

It also more easily lends itself to skipping over the details of the
defining expression when reading code aloud or in your head (e.g.
"while value is not None, where value comes from read_next_item()"
would be a legitimate way of reading the above for loop header, and
you could drop the trailing clause completely when the details aren't
particularly relevant). Avoiding the use of a colon as part of the
syntax also means that if we wanted to, we could potentially allow
optional type annotations in from-expressions ("target: annotation
from expression"), and even adopt them as a shorthand for the sentinel
pattern in function declarations (more on that below).

As far as the connection with "from module import name" goes, given
the proposed PEP 572 semantics, these three statements would all be
equivalent:

from dotted.module import name
name = __import__("dotted_module", fromlist=["name"]).name
name from __import__("dotted_module", fromlist=["name"]).name

Other examples from the PEP:

# Handle a matched regex
if (match from pattern.search(data)) is not None:
...

# Share a subexpression between a comprehension filter clause and its output
filtered_data = [y for x in data if (y from f(x)) is not None]

# Nested assignments
assert 0 == (x from (y from (z from 0)))

# Re-using fields in a container display
stuff = [[y from f(x), x/y] for x in range(5)]

And the set/dict examples display where ":=" could be visually confusing:

# Set display with local name bindings
data = {
value_a from 1,
value_b from 2,
value_c from 3,
}

# Dict display with local key & value name bindings
data = {
key_a from 'a': value_a from 1,
key_b from 'b': value_b from 2,
key_c from 'c': value_c from 3,
}

Potential extension to simplifying the optional
non-shared-mutable-default-argument pattern:

 # Shared mutable default (stored directly in f.__defaults__)
 def f(shared = []):
 

 # Unshared mutable default (implementation details TBD)
 def f(unshared from []):
 

That last part would only be a potential extension beyond the scope of
PEP 572 (since it would go against the grain of "name = expression"
and "name from expression" otherwise being functionally equivalent in
their behaviour), but it's an opportunity that wouldn't arise if a
colon is part of the expression level name binding syntax.

Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-14 Thread Nikolaus Rath
On Apr 14 2018, Chris Angelico  
wrote:
> On Fri, Apr 13, 2018 at 11:30 PM, Peter O'Connor
>  wrote:
>> Well this may be crazy sounding, but we could allow left or right assignment
>> with
>>
>> name := expr
>> expr =: name
>>
>> Although it would seem to violate the "only one obvious way" maxim, at least
>> it avoids this overloaded meaning with the "as" of "except" and "with"
>>
>
> Hah. It took me multiple readings to even notice the change in the
> operator there, so I think this would cause a lot of confusion.

Well, if putting the expression first is generally considered better,
the reasonable thing to do would be to allow *only* =:.

-Best
Nikolaus
-- 
GPG Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F

 »Time flies like an arrow, fruit flies like a Banana.«
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-13 Thread Chris Angelico
On Sat, Apr 14, 2018 at 7:33 AM, Kirill Balunov  wrote:
>
>
> 2018-04-13 23:31 GMT+03:00 Chris Angelico :
>>
>>
>> > # but these are subtly different and will be a trap for the unwary
>> > with expression as name:  # name is set to __enter__()
>> > with (expression as name):  # name is not set to __enter__()
>>
>> And that's a good reason to reject the last one with a SyntaxError,
>> but that creates an odd discrepancy where something that makes perfect
>> logical sense is rejected.
>>
>
> Maybe it does not suit you, but what do you think about `SyntaxWarning`
> instead of `SyntaxError` for both `with` and `except`. By analogy how it was
> done for `global name` into function body prior to Python 3.6?

Warnings are often not seen. For an error this subtle, a warning
wouldn't be enough.

Good call though; that was one of the considerations, and if we knew
for sure that warnings could be seen by the right people, they could
be more useful for these cases.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-13 Thread Chris Angelico
On Fri, Apr 13, 2018 at 11:30 PM, Peter O'Connor
 wrote:
> Well this may be crazy sounding, but we could allow left or right assignment
> with
>
> name := expr
> expr =: name
>
> Although it would seem to violate the "only one obvious way" maxim, at least
> it avoids this overloaded meaning with the "as" of "except" and "with"
>

Hah. It took me multiple readings to even notice the change in the
operator there, so I think this would cause a lot of confusion. (Don't
forget, by the way, that an expression can be a simple name, and an
assignment target can be more complicated than a single name, so it
won't always be obvious on that basis.) It probably wouldn't
*technically* conflict with anything, but it would get extremely
confusing!

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-13 Thread Steven D'Aprano
On Fri, Apr 13, 2018 at 05:04:00PM +0200, Jacco van Dorp wrote:

> > I'm saying, don't even try to distinguish between the forms with or
> > without parens. If we add parens:
> >
> > with (expr as name):
> >
> > it may or may not be allowed some time in the future (since it isn't
> > allowed now, but there are many requests for it) but if it is allowed,
> > it will still mean a context manager and not assignment expression.
> >
> > (In case it isn't obvious, I'm saying that we need not *require* parens
> > for this feature, at least not if the only reason for doing so is to
> > make the with/except case unambiguous.)
> >
> 
> So if I read this correctly, you're making an argument to ignore parens ?

You can always add unneeded parentheses for grouping that have no 
effect:

py> value = ( 1 )) + (((1))
py> value
2


One should never be penalised by the interpreter for unnecessary 
parentheses. If they do nothing, it shouldn't be an error. Do you really 
want an error just because you can't remember operator precendence?

flag = (spam is None) or (len(spam) == 0)

The parens are unnecessary, but I still want to write them. That 
shouldn't be an error.


> If I'd type with (expr as name) as othername:, I'd expect the original value
> of expr in my name and the context manager's __enter__ return value in
> othername. I don't really see any ambiguity in that case.

That case would be okay. But the ambiguity comes from this case:

with expr as name: 


That could mean either of:

1. Assignment-as-expression, in which case  gets set to the value 
of  and __enter__ is never called;

2. With-statement context manager, in which case  gets set to the 
value of .__enter__().

(This assumes that assignment-expressions don't require parens. For the 
case where they are required, see below.)

That's a subtle but important difference, and it is especially awful 
because most of the time it *seems* to work. Until suddenly it doesn't.

The problem is that the most common context manager objects return 
themselves from __enter__, so it doesn't matter whether  is set to 
 or .__enter__(), the result will be the same.

But some context managers don't work like that, and so your code will 
have a non-obvious bug just waiting to bite.


How about if we require parentheses? That will mean that we treat these 
two statements as different:

with expr as name:  # 1

with (expr as name):  # 2

Case #1 is of course the current syntax, and it is fine as it is.

It is the second case that has problems. Suppose the expression is 
really long, as so you innocently intend to write:

with (really
  long 
  expression) as name:

but you accidently put the closing parenthesis in the wrong place:

with (really
  long 
  expression as name):


as is easy enough to do. And now you have a suble bug: name will no 
longer be set to the result of calling __enter__ as you expect.

It is generally a bad idea to have the presence or absense of 
parentheses *alone* to make a semantic difference. With very few 
exceptions, it leads to problems. For example, if you remember except 
clauses back in the early versions of Python 2, or 1.5, you will 
remember the problems caused by treating:

except NameError, ValueError:

except (NameError, ValueError):

as every-so-subtly different. If you don't remember Python that long 
ago, would you like to guess the difference?


> Without parens -> old syntax + meaning
> with parens -> bind expr to name, because that's what the parens say.

It isn't the parentheses that cause the binding. It is the "as". So if 
you move a perfectly innocent assignment-expression into a with 
statement, the result will depend on whether or not it came with 
parentheses:


# these do the same thing
while expression as name:
while (expression as name):

# so do these
result = [1, expression as name, name + 2]
result = [1, (expression as name), name + 2]

# but these are subtly different and will be a trap for the unwary
with expression as name:  # name is set to __enter__()
with (expression as name):  # name is not set to __enter__()


Of course, we could insist that parens are ALWAYS required around 
assignment-expressions, but that will be annoying.



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-13 Thread Ethan Furman

On 04/13/2018 05:02 AM, Jacco van Dorp wrote:


I must admit I like putting the expression first, though. Even if it's
just to make it harder to mix it up with normal assignment. Perhaps =>
could be used - it's a new token, unlike -> which is used to annotate
return values, it's not legal syntax now(so no backwards compatibility
issues), and used a for similar purposes in for example php when
declaring associative arrays.($arr = array("key"=>"value");). I'm not
convinced myself, though.


The problem with => is that it's the opposite of >= which means typos would not 
cause SyntaxError and be hard to spot.

--
~Ethan~

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-13 Thread Peter O'Connor
Well this may be crazy sounding, but we could allow left or right
assignment with

name := expr
expr =: name

Although it would seem to violate the "only one obvious way" maxim, at
least it avoids this overloaded meaning with the "as" of "except" and "with"



On Fri, Apr 13, 2018 at 9:29 AM, Ethan Furman  wrote:

> On 04/13/2018 06:18 AM, Steven D'Aprano wrote:
>
>> On Fri, Apr 13, 2018 at 09:56:35PM +1000, Chris Angelico wrote:
>>
>
> If we agree that the benefit of putting the expression first is
>> sufficiently large, or that the general Pythonic look of "expr as name"
>> is sufficiently desirable (it just looks and reads nicely), then we can
>> afford certain compromises. Namely, we can rule that:
>>
>>  except expr as name:
>>  with expr as name:
>>
>> continue to have the same meaning that they have now and never mean
>> assignment expressions. Adding parens should not change that.
>>
>
> +1
>
> In other words, the rule is that "expr as name" keeps its current, older
>> semantics in with and except statements, and NEVER means the new, PEP
>> 572 assignment expression.
>>
>> Yes, that's a special case that breaks the rules, and I accept that it
>> is a point against "as". But the Zen is a guideline, not a law of
>> physics, and I think the benefits of "as" are sufficient that even
>> losing a point it still wins.
>>
>
> +1
>
> 2) Forbid any use of "(expr as name)" in the header of a 'with' statement
>>>
>>
>> You can't forbid it, because it is currently allowed syntax (albeit
>> currently without the parens). So the rule is, it is allowed, but it
>> means what it meant pre-PEP 572.
>>
>
> +1
>
> If people agree with me that it is important to put the expression first
>> rather than the target name, then the fact that statements and for loops
>> put the name first shouldn't matter.
>>
>
> +1 to expression coming first!  ;)
>
> --
> ~Ethan~
>
>
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-13 Thread Chris Angelico
On Fri, Apr 13, 2018 at 9:04 PM, Steven D'Aprano  wrote:
> On Wed, Apr 11, 2018 at 03:32:04PM +1000, Chris Angelico wrote:
>
>> In any context where arbitrary Python expressions can be used, a **named
>> expression** can appear. This can be parenthesized for clarity, and is of
>> the form ``(target := expr)`` where ``expr`` is any valid Python expression,
>> and ``target`` is any valid assignment target.
>
> Have we really decided on spelling this as `target := expression`? You
> list this as a rejected spelling:
>
>
>> 1. ``EXPR as NAME``, with or without parentheses::
>>
>>stuff = [[f(x) as y, x/y] for x in range(5)]
>
> but I don't think the objections given should be fatal:
>
>>Omitting the parentheses in this form of the proposal introduces many
>>syntactic ambiguities.  Requiring them in all contexts leaves open the
>>option to make them optional in specific situations where the syntax is
>>unambiguous (cf generator expressions as sole parameters in function
>>calls), but there is no plausible way to make them optional everywhere.
>>
>>With the parentheses, this becomes a viable option, with its own tradeoffs
>>in syntactic ambiguity.  Since ``EXPR as NAME`` already has meaning in
>>``except`` and ``with`` statements (with different semantics), this would
>>create unnecessary confusion or require special-casing.
>
> The special casing you refer to would be to prohibit name binding
> expressions in "except" and "with" statements. You should explicitly say
> so in the PEP.

Parenthesis added to the rejection paragraph.

> I don't think that prohibiting those two forms is a big loss. I think
> any form of
>
> except (name := expression) as err:
> do_something(name)
>
> is going to be contrived. Likewise for `with` statements.

I agree as regards except statements. Not so much the with statements,
though. How many times have people asked for "with (expr as name):" to
be supported, allowing the statement to spread over multiple lines?
With this syntax, it would suddenly be permitted - with dangerously
similar semantics. For many MANY context managers, "with (expr as
name):" would do the exact same thing as "with expr as name:". There
is a general expectation that adding parentheses to an expression
usually doesn't change the behaviour, and if it's legal, people will
assume that the behaviour is the same. It isn't, and it's such a
sneaky difference that I would call it a bug magnet.

So if it's a bug magnet, what do we do?

1) Permit the subtly different semantics, and tell people to be careful
2) Forbid any use of "(expr as name)" in the header of a 'with' statement
3) Forbid it at top level, but permit it deeper down
4) Something else??

> I don't especially dislike := but I really think that putting the
> expression first is a BIG win for readability. If that requires parens
> to disambiguate it, so be it.

There's a mild parallel between "(expr as name)" and other uses of
'as', which bind to that name. Every other use of 'as' is part of a
special syntactic form ('import', 'with', and 'except'), but they do
all bind to that name. (Point of interest: You can "with expr as
x[0]:" but none of the other forms allow anything other than a simple
name.) There's a strong parallel between "target := value" and "target
= value"; in fact, the section on the differences is incredibly short
and could become shorter. The only really important difference is that
augmented assignment is not supported (you can't say "x +:= 5"),
partly because it'd mean creating a boatload of three-character
operators for very little value, and partly because
augmented-assignment-as-expression is hard to explain.

Which is better? A weak parallel or a strong one? How important is
putting the expression first? On balance, I'm currently in favour of
the := syntax, but it's only a small difference.

> You also missed the "arrow assignment operator" from various languages,
> including R:
>
> expression -> name
>
> (In an earlier post, I suggested R's other arrow operator, name <- expr,
> but of course that already evaluates as unary minus expr.)

I actually can't find anything about the -> operator, only the <- one.
(Not that I looked very hard.) Is it a truly viable competitor, or
just one that you'd like to see mentioned for completeness?

> I think that there should be more attention paid to the idea of putting
> the expression first, rather than the name.

How many ways are there to bind a value to a name?

Name last:
* import x as y
* from x import y as z
* except x as y
* with x as y

Name first:
* x = y
* x += y # etc
* for x in y
* def x(.) 
* def f(x=1) - arg defaults
* class X: ...

I'm seeing consistency here in that *EVERY* name binding where the
name is at the end uses "as target" as its syntax. Everything else
starts with the target, then defines what's being assigned to it. So I
don't see much value in a "->" operator, except for the mere