Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)
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)
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)
> 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)
On Tue, Apr 17, 2018 at 6:09 AM, Thautwarm Zhaowrote: > > > 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)
On Mon, Apr 16, 2018 at 8:09 PM, Thautwarm Zhaowrote: > > > 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)
> 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)
On Mon, Apr 16, 2018 at 11:11 AM Ned Batchelderwrote: > 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)
On Tue, Apr 17, 2018 at 5:11 AM, Steve Barneswrote: > >> 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)
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)
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)
On Mon, Apr 16, 2018 at 11:05 PM, Mikhail Vwrote: > 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)
On 16 April 2018 at 00:27, Thautwarm Zhaowrote: > 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)
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)
On Sun, Apr 15, 2018 at 6:58 PM, Steven D'Apranowrote: > 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)
[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-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)
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)
On Mon, Apr 16, 2018 at 4:58 AM, Thautwarm Zhaowrote: > 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)
On Sun, Apr 15, 2018 at 2:01 PM, Nick Coghlanwrote: > 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)
On Mon, Apr 16, 2018 at 3:19 AM, Guido van Rossumwrote: > 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)
On Mon, Apr 16, 2018 at 12:17 AM, Kirill Balunovwrote: > > > 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)
On Mon, Apr 16, 2018 at 1:58 AM, Steven D'Apranowrote: > 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 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)
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)
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)
> > > 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)
> 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 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)
On Sun, Apr 15, 2018 at 7:19 PM, Kirill Balunovwrote: >> === 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 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)
On 15 April 2018 at 19:41, Mikhail Vwrote: > 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)
On Sun, Apr 15, 2018 at 12:19 PM, Kirill Balunovwrote: > > > 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 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)
On 15 April 2018 at 13:54, Chris Angelicowrote: > 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)
On Sat, Apr 14, 2018 at 11:54 PM, Chris Angelicowrote: > 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)
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)
On Sun, Apr 15, 2018 at 1:08 PM, Nick Coghlanwrote: > === 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)
On 13 April 2018 at 23:18, Steven D'Apranowrote: > 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)
On Apr 14 2018, Chris Angelicowrote: > 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)
On Sat, Apr 14, 2018 at 7:33 AM, Kirill Balunovwrote: > > > 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)
On Fri, Apr 13, 2018 at 11:30 PM, Peter O'Connorwrote: > 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)
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)
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)
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 Furmanwrote: > 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)
On Fri, Apr 13, 2018 at 9:04 PM, Steven D'Apranowrote: > 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