Re: Behavior of the for-else construct
On 2022-03-07 06:00:57 -0800, Grant Edwards wrote: > On 2022-03-07, Peter J. Holzer wrote: > > On 2022-03-06 18:34:39 -0800, Grant Edwards wrote: > >> On 2022-03-06, Avi Gross via Python-list wrote: > >> > Python is named after a snake right? > >> > >> No. It's named after a comedy troupe. > > > > He actually wrote that two sentences later. > > Yes, I missed that. His messages wrap very strangely in my newsreader. Yes, he writes every paragraph as a single long line which makes it hard to read. hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | h...@hjp.at |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
Op 4/03/2022 om 02:08 schreef Avi Gross via Python-list: If Python was being designed TODAY, I wonder if a larger set of key words would be marked as RESERVED for future expansion including ORELSE and even NEVERTHELESS. I think a better solution would be to have reserved words written letters form the mathematical lettter block. Something like: 퐝퐞퐟 foo(bar): in = file(...) 퐟퐨퐫 line 퐢퐧 in: ... -- https://mail.python.org/mailman/listinfo/python-list
Non sequitur: Changing subject line... WAS: Behavior of the for-else construct
On Mon, 7 Mar 2022 18:07:42 +, "Schachner, Joseph" declaimed the following: >Can someone please change the topic of this thread? No longer about for-else. > Pretty much anyone can change the subject of the message when replying. But if one is using a threaded client, that thread on message references Message-ID: References: <621325684.471007.1646354302...@mail.yahoo.com> <20220304225746.mmebv3myg5wbp...@hjp.at> <657845041.42944.1646437629...@mail.yahoo.com> <20220305001158.g7rmlyoxxtxuf...@hjp.at> <1mc72hll06itd6jnbgdherqb3thf1fk...@4ax.com> <20220306163951.2ozmrhfbtsktb...@hjp.at> it will still appear under the parent message; it will only thread differently if one's client merely sorts on subject and date/time. -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
RE: Behavior of the for-else construct
Can someone please change the topic of this thread? No longer about for-else. Teledyne Confidential; Commercially Sensitive Business Data -Original Message- From: Dennis Lee Bieber Sent: Sunday, March 6, 2022 1:29 PM To: python-list@python.org Subject: Re: Behavior of the for-else construct On Sun, 6 Mar 2022 17:39:51 +0100, "Peter J. Holzer" declaimed the following: > >(* *) for comments was actually pretty commonly used - maybe because it >stands out more than { }. I don't know if I've ever seen (. .) instead >of [ ]. > Or some terminals provided [ ] but not { } Modula-2 appears to have fixed on (* *) for comments, and only [ ] for indexing. Consider the potential mayhem going from a language where { } are comment delimiters to one where they are block delimiters >C also has alternative rerpresentations for characters not in the >common subset of ISO-646 and EBCDIC. However, the trigraphs are >extremely ugly (e.g ??< ??> instead of { }). I have seen them used (on >an IBM/390 system with an EBCDIC variant without curly braces) and it's >really no fun to read that. > My college mainframe used EBCDIC, but the available languages did not include C or Pascal. We had APL, FORTRAN-IV (in full separate compilation form, and FLAG [FORTRAN Load and Go] which was a "all in one file, compile & run" used by first year students), COBOL (74?), BASIC, SNOBOL, Meta-Symbol and AP (both assemblers, though Meta-Symbol could, provided the proper definition file, generate absolute binary code for pretty much any processor), and something called SL-1 (Simulation Language-1, which produced FORTRAN output for discrete event models). UCSD Pascal, and PDP-11 assembly were run on a pair of LSI-11 systems. Assembly used for the operating system principles course. I didn't encounter "real" C until getting a TRS-80 (first as integer LC, then Pro-MC), along with Supersoft LISP (on cassette tape!). (I had books for C and Ada before encountering compilers for them) -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-07, Peter J. Holzer wrote: > On 2022-03-06 18:34:39 -0800, Grant Edwards wrote: >> On 2022-03-06, Avi Gross via Python-list wrote: >> > Python is named after a snake right? >> >> No. It's named after a comedy troupe. > > He actually wrote that two sentences later. Yes, I missed that. His messages wrap very strangely in my newsreader. -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-06 18:34:39 -0800, Grant Edwards wrote: > On 2022-03-06, Avi Gross via Python-list wrote: > > Python is named after a snake right? > > No. It's named after a comedy troupe. He actually wrote that two sentences later. hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | h...@hjp.at |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-06, Avi Gross via Python-list wrote: > Python is named after a snake right? No. It's named after a comedy troupe. -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Sun, 6 Mar 2022 17:39:51 +0100, "Peter J. Holzer" declaimed the following: > >(* *) for comments was actually pretty commonly used - maybe because it >stands out more than { }. I don't know if I've ever seen (. .) instead >of [ ]. > Or some terminals provided [ ] but not { } Modula-2 appears to have fixed on (* *) for comments, and only [ ] for indexing. Consider the potential mayhem going from a language where { } are comment delimiters to one where they are block delimiters >C also has alternative rerpresentations for characters not in the common >subset of ISO-646 and EBCDIC. However, the trigraphs are extremely ugly >(e.g ??< ??> instead of { }). I have seen them used (on an IBM/390 >system with an EBCDIC variant without curly braces) and it's really no >fun to read that. > My college mainframe used EBCDIC, but the available languages did not include C or Pascal. We had APL, FORTRAN-IV (in full separate compilation form, and FLAG [FORTRAN Load and Go] which was a "all in one file, compile & run" used by first year students), COBOL (74?), BASIC, SNOBOL, Meta-Symbol and AP (both assemblers, though Meta-Symbol could, provided the proper definition file, generate absolute binary code for pretty much any processor), and something called SL-1 (Simulation Language-1, which produced FORTRAN output for discrete event models). UCSD Pascal, and PDP-11 assembly were run on a pair of LSI-11 systems. Assembly used for the operating system principles course. I didn't encounter "real" C until getting a TRS-80 (first as integer LC, then Pro-MC), along with Supersoft LISP (on cassette tape!). (I had books for C and Ada before encountering compilers for them) -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Mon, 7 Mar 2022 at 09:51, Avi Gross via Python-list wrote: > > >>> > Pascal versus PASCAL versus pascal (not versus paschal) and > Perl versus PERL versus perl (not versus pearl) > > seems to be a topic. > <<< > > The nitpickers here are irrelevant. I happen to know how things are formally > spelled and if I was publishing a book, might carefully proofread it. So what you're saying is that you don't really care unless it's in a book. Good to know. I make errors now and then, but I consider them to be errors, and I would like to reduce their number. > Python is named after a snake right? So is it upper case or lower case or > mixed case? No, wait, it is named after Monty Python. But what made them > choose that name and why would anyone then name a programming language after > them? I can see some rudimentary reasoning in naming Ada and maybe for > Pascal, albeit I can think of many others who deserve it as much or more that > nobody has chosen to honor. Did Turing catch on, I mean as a programming > language rather than a machine? > If you want strange naming conventions, apparently there's "Apache Pig Latin", "Ballerina", "Hopscotch", "Mercury", and even this bizarre thing called "ECMAScript", can't possibly imagine why anyone would use a thing like that, right? Things get named, usually by their creators. Deliberately misnaming something is insulting it. > I don't care if someone says PYTHON or Python or python when informally > discussing things. They all mean the same thing to me. On the other hand, > names like "R" and "S" and "C" are rarely presented as lower-case while I > sometimes see c++ or c# for some reason. Obviously the right version is upper > case, albeit the plus sign and sharp sign have no upper case version. > > FORTRAN supposedly stands for FORmula TRANslator or something. So why does it > have to be all uppercase? Was COBOL named for COmmon Business Oriented > Language. Should it be CoBOL? > Because that's what their creators decided. Or are you in a more authoritative position? I think you should have been named AVI144, not Avi Gross. We shouldn't bother to try to call you by your name, it's much more reasonable to call you something else. > But if this was being graded in these ways, and I see lots of such nitpicking > in other ways when an example focusing on something does not carefully do > lots of other things, I probably would focus on the many other things I don't > get around to doing in my life because I waste the time here. As a voluntary > effort, I can opt out. > > The argument that a programming language is named after a person and thus > must be spelled some way is not impressing me. Yes, to be strictly correct, > it has a proper spelling. But following that reasoning, why does anyone give > an email address of john.sm...@gmail.com or jane...@yahoo.com instead of ...? > Email addresses consist of a mailbox part, interpreted entirely by the server, and a domain, which is defined as case insensitive and conventionally written in lowercase. There's no difference between john.sm...@gmail.com and john.sm...@gmail.com, but it's up to Google's servers to decide whether john.smith is the same as JOHN.SMITH (and, in the case of Google, they've decided that it's the same as johnsmith and johns.mith too). ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
>>> Pascal versus PASCAL versus pascal (not versus paschal) and Perl versus PERL versus perl (not versus pearl) seems to be a topic. <<< The nitpickers here are irrelevant. I happen to know how things are formally spelled and if I was publishing a book, might carefully proofread it. I sometimes use upper case for Emphasis and do not give a dAMN. But feel free to correct my spelling in case you suspect someone here truly misunderstood a message because it was written with the wrong case. I do learn, but when it is something I already know and am not particularly interested in proofreading, the result tends to be that I simply get annoyed and the one pointing it out is taken as wandering off topic even more than I do. Python is named after a snake right? So is it upper case or lower case or mixed case? No, wait, it is named after Monty Python. But what made them choose that name and why would anyone then name a programming language after them? I can see some rudimentary reasoning in naming Ada and maybe for Pascal, albeit I can think of many others who deserve it as much or more that nobody has chosen to honor. Did Turing catch on, I mean as a programming language rather than a machine? I don't care if someone says PYTHON or Python or python when informally discussing things. They all mean the same thing to me. On the other hand, names like "R" and "S" and "C" are rarely presented as lower-case while I sometimes see c++ or c# for some reason. Obviously the right version is upper case, albeit the plus sign and sharp sign have no upper case version. FORTRAN supposedly stands for FORmula TRANslator or something. So why does it have to be all uppercase? Was COBOL named for COmmon Business Oriented Language. Should it be CoBOL? I have lots of awareness that Perl is generally written in mixed case, except when it isn't. I have seen people justify the name by saying it was short for Practical Extraction and Report Language but also for Pathologically Eclectic Rubbish Lister! If I felt it was important, I would write it whatever way is formally required. What I think often happens, from a human psychology perspective, is we see Perl in middle of a sentence as a spelling mistake while PERL is obviously something like an acronym. Pascal may be named for a French person I admire but may still look like a nonsense word to those who do not know or care. Not a great excuse, of course. But if this was being graded in these ways, and I see lots of such nitpicking in other ways when an example focusing on something does not carefully do lots of other things, I probably would focus on the many other things I don't get around to doing in my life because I waste the time here. As a voluntary effort, I can opt out. The argument that a programming language is named after a person and thus must be spelled some way is not impressing me. Yes, to be strictly correct, it has a proper spelling. But following that reasoning, why does anyone give an email address of john.sm...@gmail.com or jane...@yahoo.com instead of ...? -Original Message- From: Peter J. Holzer To: python-list@python.org Sent: Sun, Mar 6, 2022 12:48 pm Subject: Re: Behavior of the for-else construct On 2022-03-06 09:29:19 -0800, Grant Edwards wrote: > On 2022-03-05, Avi Gross via Python-list wrote: > > I am not sure how we end up conversing about PASCAL on a Python > > forum. > > [...] > > I paid no attention to where PASCAL was being used other than I did > > much of my grad school work in PASCAL [...] > > It's "Pascal". It's not an acronym. It's a guy's name: > > https://en.wikipedia.org/wiki/Blaise_Pascal And similarly, it's "Perl", not "PERL" (also misspelled in this thread). hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | h...@hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-06 09:29:19 -0800, Grant Edwards wrote: > On 2022-03-05, Avi Gross via Python-list wrote: > > I am not sure how we end up conversing about PASCAL on a Python > > forum. > > [...] > > I paid no attention to where PASCAL was being used other than I did > > much of my grad school work in PASCAL [...] > > It's "Pascal". It's not an acronym. It's a guy's name: > > https://en.wikipedia.org/wiki/Blaise_Pascal And similarly, it's "Perl", not "PERL" (also misspelled in this thread). hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | h...@hjp.at |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-05, Avi Gross via Python-list wrote: > I am not sure how we end up conversing about PASCAL on a Python > forum. > [...] > I paid no attention to where PASCAL was being used other than I did > much of my grad school work in PASCAL [...] It's "Pascal". It's not an acronym. It's a guy's name: https://en.wikipedia.org/wiki/Blaise_Pascal -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-05 14:25:35 -0500, Dennis Lee Bieber wrote: > On Sat, 5 Mar 2022 12:39:36 -0600, "Michael F. Stemper" > declaimed the following: > >... especially Pascal, which was probably bigger in Germany and Austria > >in the 1980s than was C. > > Pascal also defined alternate representations (per Jensen) for > some of those (and I don't recall ever seeing a system that actually had an > up-arrow character -- and selecting one in character map doesn't help, my > client doesn't render it). > > directalternate > ? ^ or @ > [ (. > ] .) > { (* > } *) (* *) for comments was actually pretty commonly used - maybe because it stands out more than { }. I don't know if I've ever seen (. .) instead of [ ]. C also has alternative rerpresentations for characters not in the common subset of ISO-646 and EBCDIC. However, the trigraphs are extremely ugly (e.g ??< ??> instead of { }). I have seen them used (on an IBM/390 system with an EBCDIC variant without curly braces) and it's really no fun to read that. hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | h...@hjp.at |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
I am not clear on what you are commenting, Dennis. You are responding to what I do not believe I wrote. You did not quote the part of my message where I wrote what "I" did in the early 80's and did not say when PASCAL was available elsewhere. "I paid no attention to where PASCAL was being used other than I did much of my grad school work in PASCAL in the early 80's including my thesis being a document that could be typeset or run from the same file ;-)" I might have encountered it in the early 70's had I had any room in my college course schedule where I ended up with a triple major in other subjects or while I was in Medical school. But no, I only went back to study C.S. afterwards. So, I apologize for being late. Heck I was also not there when ALGOL was created or FORTRAN, let alone COBOL! But if it helps, I taught FORTRAN and other languages to undergrads ;-) -Original Message- From: Dennis Lee Bieber To: python-list@python.org Sent: Sat, Mar 5, 2022 7:00 pm Subject: Re: Behavior of the for-else construct On Sat, 5 Mar 2022 21:40:08 + (UTC), Avi Gross declaimed the following: >I am not sure how we end up conversing about PASCAL on a Python forum. But it >is worth considering how people educated in aspects of Computer Science often >come from somewhat different background and how it flavors what they do now. > You'd prefer REBOL, perhaps? REXX at least has some structure to it NB: Pascal has, like Ada, always been a name -- not like the origins of COBOL, FORTRAN, BASIC, et al. >I paid no attention to where PASCAL was being used other than I did much of my >grad school work in PASCAL in the early 80's including my thesis being a >document that could be typeset or run from the same file ;-) > Very early? The common versions were probably UCSD (running on UCSD P-System); or a port of the P-4 compiler (which had been published in book form) -- maybe a "tinyPascal" (integer only I suspect). Radio Shack did provide Alcor Pascal for the TRS-80. Later, you might have encountered TurboPascal -- which bore little resemblance to a Jensen Pascal. J was one-program<>one-file (no link libraries, no "include" files as I recall); very limited math functions if one is trying for scientific applications (sin, cos, arctan were the trig functions I recall), and that very unfriendly I/O system (console I/O required special handling from file I/O as Pascal does a one-element pre-read when an I/O channel is opened -- which occurs on program load for stdin, much before a program could output a prompt to the user). Even my first exposure to VAX/VMS Pascal, which did allow for separate compilation and linking, required me to declare interfaces to the FORTRAN run-time library to get advanced math functions (I believe later versions incorporated the FORTRAN math natively). -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Sat, 5 Mar 2022 21:40:08 + (UTC), Avi Gross declaimed the following: >I am not sure how we end up conversing about PASCAL on a Python forum. But it >is worth considering how people educated in aspects of Computer Science often >come from somewhat different background and how it flavors what they do now. > You'd prefer REBOL, perhaps? REXX at least has some structure to it NB: Pascal has, like Ada, always been a name -- not like the origins of COBOL, FORTRAN, BASIC, et al. >I paid no attention to where PASCAL was being used other than I did much of my >grad school work in PASCAL in the early 80's including my thesis being a >document that could be typeset or run from the same file ;-) > Very early? The common versions were probably UCSD (running on UCSD P-System); or a port of the P-4 compiler (which had been published in book form) -- maybe a "tinyPascal" (integer only I suspect). Radio Shack did provide Alcor Pascal for the TRS-80. Later, you might have encountered TurboPascal -- which bore little resemblance to a Jensen Pascal. J was one-program<>one-file (no link libraries, no "include" files as I recall); very limited math functions if one is trying for scientific applications (sin, cos, arctan were the trig functions I recall), and that very unfriendly I/O system (console I/O required special handling from file I/O as Pascal does a one-element pre-read when an I/O channel is opened -- which occurs on program load for stdin, much before a program could output a prompt to the user). Even my first exposure to VAX/VMS Pascal, which did allow for separate compilation and linking, required me to declare interfaces to the FORTRAN run-time library to get advanced math functions (I believe later versions incorporated the FORTRAN math natively). -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 05Mar2022 17:48, Avi Gross wrote: >Since we still seem to be dreaming, I wonder when someone will suggest using >some variation of the new match statement. Ugh :-) But... What if break were implemented with an exception, like StopIteration but for interruption instead of stop? And for-loops were an implied try/except: for ... except BrokenIteration: # <-- implied pass and you could go: for ... except BrokenIteration: ... a break occurred else: ... a break did not occur and, indeed, for ... except BrokenIteration: ... a break occurred except StopIteration as stopped: print("I did", stopped.count, "iterations") else: # not reached because of the "except StopIteration" above ... a break did not occur if we wanted to cover off the count iterations wish item. Cheers, Cameron Simpson -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
I am not sure how we end up conversing about PASCAL on a Python forum. But it is worth considering how people educated in aspects of Computer Science often come from somewhat different background and how it flavors what they do now. I paid no attention to where PASCAL was being used other than I did much of my grad school work in PASCAL in the early 80's including my thesis being a document that could be typeset or run from the same file ;-) And my first job in the field also was doing programming in PASCAL. At the time it seemed to be a new and upcoming language with lots of nifty features. It seemed to have so many ways it was an improvement on languages I had been using including BASIC and Fortran and versions of LISP. So it was a tad surprising when my next job at Bell Labs focused on C (and later C++) as well as a large array of utilities and small languages in the UNIX world. PASCAL was nowhere to be seen nor others that arrived to take over the world like Modula and Ada, and yet didn't. It depends where you are and on your perspective, and perhaps it survived in places like Europe and often has been enhanced. We have mentioned how things like Fortran keep evolving and, in any case, tons of the code we use in aspects of Python and especially some add-in modules, is from libraries of well-honed libraries of functions written in Fortran or C or I am sure in some cases even assembler languages. I wonder if some languages of the future may supersede languages like Python but retain aspects of them in a similar way? As a hobby, I study lots of languages to see if they add anything or are likely to take over. Some seem to really be focused on a company like Microsoft or Google using it for their own purposes and others who wish to play in their arena may have to go along to operate there. Others seem to be the kind of things academics invent to play with various ideas. So will SCALA or GO or RUST become major players or will they wither away? Will languages that make major changes that make older software not compatible, think Python or PERL as examples, end up stronger or ... motivate some to abandon their projects and switch to a new language/system/paradigm? I do a lot of data manipulation in an assortment of languages including multiple methods within a language. I can sometimes see how a person asking for features or writing programs has been influenced by earlier experiences. Database people who started with a relational database and mainly used some dialect of SQL, may face some problems in their own way and think making lots of smaller tables in third normal form and constantly doing all kinds of table merges is the natural way to do things. Those who start doing things using Python or R may view things quite differently and often see ways to do things gradually and in a pipelined method and not do what is seen as expensive operations like some kinds of merge. I am not saying everyone does things in a stereotypical way, just that people learn tools and methods and it may show. Given how much faster some things have become, even hybrid programmers may play games. Yes, you can issue SQL to load data from a database into your Python or R programs but some issue a very basic command and then massage it locally while others do most of the processing in the SQL component so that less is dragged in. Some habits persist even after circumstances change. I have little against PASCAL and have not looked at how it has evolved but found it a very limiting language after a while. But I find most languages somewhat limited and now think they should be. What makes a language great for me is if it does not try to be too complete but provides a way to extend it so people can come up with their own ways to do more complex things, including various ways to do graphics or statistical analyses and so on, as sort of add-ons which become little languages or worlds grafted on when needed and ignored when not. Python qualifies albeit it is already too bloated! LOL! Avi Palm: 3rd digit from the right, vertically. -Original Message- From: Michael F. Stemper To: python-list@python.org Sent: Sat, Mar 5, 2022 1:39 pm Subject: Re: Behavior of the for-else construct On 04/03/2022 18.11, Peter J. Holzer wrote: > On 2022-03-04 23:47:09 +, Avi Gross via Python-list wrote: >> I am not sure a reply is needed, Peter, and what you say is true. But >> as you point out, when using a German keyboard, I would already have >> a way to enter symbols like ä, ö, ü and ß and no reason not to include >> them in variable names and so on if UNICODE is being used properly. I >> can use my last name in German notation as a variable in Python now: >> >> Groß = 144 >> Groß / 12 >> 12.0 > > Yes, I'm using umlauts occasionally in variable names in Python, and > I've also used Greek charac
Re: Behavior of the for-else construct
On 04/03/2022 18.11, Peter J. Holzer wrote: On 2022-03-04 23:47:09 +, Avi Gross via Python-list wrote: I am not sure a reply is needed, Peter, and what you say is true. But as you point out, when using a German keyboard, I would already have a way to enter symbols like ä, ö, ü and ß and no reason not to include them in variable names and so on if UNICODE is being used properly. I can use my last name in German notation as a variable in Python now: Groß = 144 Groß / 12 12.0 Yes, I'm using umlauts occasionally in variable names in Python, and I've also used Greek characters and others. But in Python I CAN use them. I DON'T HAVE to. That's a big difference. Characters like [] or {} are a part of Python's syntax. You can't avoid using them. If you can't type them, you can't write Python. If it is awkward to enter them (like having to type Alt-91 or pasting them from a character table) it is painful to write programs. German keyboards aquired an AltGr key and the ability to type these characters in the mid to late 1980's. Presumably because those characters were common in C and other programming languages ... especially Pascal, which was probably bigger in Germany and Austria in the 1980s than was C. -- Michael F. Stemper Psalm 94:3-6 -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Sat, 5 Mar 2022 12:39:36 -0600, "Michael F. Stemper" declaimed the following: >... especially Pascal, which was probably bigger in Germany and Austria >in the 1980s than was C. Pascal also defined alternate representations (per Jensen) for some of those (and I don't recall ever seeing a system that actually had an up-arrow character -- and selecting one in character map doesn't help, my client doesn't render it). direct alternate ? ^ or @ [ (. ] .) { (* } *) I'll admit... (. is a clumsy sequence to type in place of [ (RH ring finger to top-row on modern keyboards followed by RH ring finger to bottom-row .), but it is a sequence any terminal mapping to a common /typewriter/ keyboard should have available. (* isn't quite as clumsy (RH ring finger to top-row followed by RH middle finger to top-row ). More fun is had when doing APL without a dedicated APL keyboard (Though Xerox Sigma APL also had plain text alternatives: $RHO for example) -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
Since we still seem to be dreaming, I wonder when someone will suggest using some variation of the new match statement. All you need is for the for loop (and possibly other such constructs) to return some kind of status that can be matched match (for var in something: ... ) : case break(): case skipped(): case did(1): case didall(): case crash(): case _ : As always, the above is not even pseudocode. But my point is there are languages I have seen that are built on such pattern matching and provide abilities to do a multi-way branching as long as you are very careful about the order you place the things to match. If not understood, the above function calls are meant to suggest something. For argument's sake, the for loop could return a non-negative number that shows the number of iterations done completely or even partially. It could also return various out-of-band (perhaps negative) values. So if it is skipped you get a zero or a value matching what my make-believe function skipped() returns. If the loop just ran once, it matched did(1). If it completed without breaks, it didall() and if it broke out, or crashed it matches something. I hope the idea comes across, even if you disagree with my indenting or exact method. Constructs like the above do in theory allow some really complex matching and often in a way easier to understand than having endless clauses added below the for group. But as repeatedly stated, Python currently has no concept of returning a value directly from a for loop or lots of other things. A brand new language that superficially resembled python could be designed but that is a rather formidable task. And where does it end? I mean you could set it up so the language allows you to return an invisible (meaning it does not print unless you ask for it) object among many possible objects. The simplest object may be an integer or perhaps an object of a class with a name like counter so you matched against counter(1) or against counter(n) if you want to capture the exact number for further processing. Various other object types might be returned including one that tells you about a break and also on which iteration it broke out of or even the value of the item it was looping on at the moment. If this starts looking a bit like how errors can be created and propagated, that is no coincidence. But the above also might come with serious overhead. And for many, it would not be seen as necessary. I will say that by allowing the match statement in the current form, the door has been opened wide for all kinds of potential enhancements. Older code and features may be left alone, but newer code is now free to do esoteric things. If I rewrote my call to the loop into a function that takes arguments including the data I want to have used and internally does the for loop while setting various variables that capture all kinds of info needed, then it potentially could return one of a series of objects you could pattern match against to your heart's content. A call to the function could be used in a match statement vaguely as in my hand-waving above. And of course you can use unpacking to make all kinds of compound patterns if done carefully. I think my part of this endless conversation may have gone a bit beyond far enough and I await some new topics. -Original Message- From: Rob Cliffe via Python-list To: python-list@python.org Sent: Sat, Mar 5, 2022 7:15 am Subject: Re: Behavior of the for-else construct On 05/03/2022 01:15, Cameron Simpson wrote: > > I sort of wish it had both "used break" and "did not use break" > branches, a bit like try/except/else. And "zero iterations". Rob Cliffe -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 05/03/2022 01:15, Cameron Simpson wrote: I sort of wish it had both "used break" and "did not use break" branches, a bit like try/except/else. And "zero iterations". Rob Cliffe -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-05 00:25:44 +0100, Peter J. Holzer wrote: > On 2022-03-04 11:34:07 +1100, Chris Angelico wrote: > > What I'm hearing is that there are, broadly speaking, two types of > > programmers [1]: > > > > 1) Those who think about "for-else" as a search tool and perfectly > > understand how it behaves > > 2) Those who have an incorrect idea about what for-else is supposed to > > do, don't understand it, and don't like it. > > 3) Those who understand what it does und don't even find it*s syntax > very confusing, yet only very rarely find it useful. > > I have probably used it a handful of times in 8 years of Python > programming. Coincidentally, I think I used it just this week - but I > can't find it any more which probably means that it was either in a > throwaway script or I have since rewritten the code. Just found it again. Not yet committed, and I may still end up rewriting it again before turning in the pull request, but for now it's the simplest solution for the problem. hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | h...@hjp.at |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 03Mar2022 14:24, computermaster360 wrote: >I want to make a little survey here. > >Do you find the for-else construct useful? Have you used it in >practice? Do you even know how it works, or that there is such a thing >in Python? I used Python for years before understanding the for-else (and therefore, without seeing a use for it). Finally made the time to wrap my head around it quite recently and have used it a few times since. It is a little niche, but when you want it, it is very nice indeed. Certainly avoids managing a special flag variable (which can be fiddly and therefore fragile) for "did my loop not run to completion"? I sort of wish it had both "used break" and "did not use break" branches, a bit like try/except/else. But not very much. Cheers, Cameron Simpson -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-04 23:47:09 +, Avi Gross via Python-list wrote: > I am not sure a reply is needed, Peter, and what you say is true. But > as you point out, when using a German keyboard, I would already have > a way to enter symbols like ä, ö, ü and ß and no reason not to include > them in variable names and so on if UNICODE is being used properly. I > can use my last name in German notation as a variable in Python now: > > Groß = 144 > Groß / 12 > 12.0 Yes, I'm using umlauts occasionally in variable names in Python, and I've also used Greek characters and others. But in Python I CAN use them. I DON'T HAVE to. That's a big difference. Characters like [] or {} are a part of Python's syntax. You can't avoid using them. If you can't type them, you can't write Python. If it is awkward to enter them (like having to type Alt-91 or pasting them from a character table) it is painful to write programs. German keyboards aquired an AltGr key and the ability to type these characters in the mid to late 1980's. Presumably because those characters were common in C and other programming languages and programmers were complaining. I assume the same happened with keyboards for other languages. These days you can assume that everybody can type all ASCII characters (and knows how to do it). But if you add arbitrary unicode characters to the syntax of your language, for example using «» to delimit code blocks and ⦃ ⦄ for sets and ∅ for None, then every programmer will have to figure out how to enter those characters. And 90 % will probably say "Fuggedaboutit, I'm not going to learn a new programming language I can't even type!" hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | h...@hjp.at |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
I am not sure a reply is needed, Peter, and what you say is true. But as you point out, when using a German keyboard, I would already have a way to enter symbols like ä, ö, ü and ß and no reason not to include them in variable names and so on if UNICODE is being used properly. I can use my last name in German notation as a variable in Python now: Groß = 144 Groß / 12 12.0 But even if I was German (and despite living in Austria for a year, I am not) I might want to write some things in French which might not be on that Keyboard, unless it includes everything in ISO 8859-1, albeit that standard is missing letters used rarely in some languages. I have also used characters from Spanish and French and Hungarian and others as names in programs with no problems, albeit getting them in is not trivial on my very solid American English keyboard but can be done many ways. A fairly simple way is to use something like this using Google translate: https://translate.google.com/?sl=de=en=translate Pick the language you want and pop up a keyboard and type a bit and then copy/paste like this: גרוס If I had to do this all the time, and occasionally I do, you can get other pop-up keyboards or helpers that take several keystrokes you memorize and convert it, ... But it rarely is worth doing this if others will be using my code and complaining or trying to edit it. Chris has already pointed out the dangers of wandering too far from standard practice and making code hard for anyone else to deal with so yes, I would not rewrite key components or do something like make new function names that point to existing standard functions and only use the new (often not pronounceable) names. -Original Message- From: Peter J. Holzer To: python-list@python.org Sent: Fri, Mar 4, 2022 5:57 pm Subject: Re: Behavior of the for-else construct On 2022-03-04 00:38:22 +, Avi Gross via Python-list wrote: > I have seen major struggles to get other character sets into > languages. Any new language typically should have this built in from > scratch and should consider adding non-ASCII characters into the mix. > Mathematicians often use lots of weird braces/brackets as an example > while normal programs are limited to [{( and maybe < and their > counterparts. This leads to odd Python behavior (other languages too) > where symbols are re-used ad nauseam. { can mean set or dictionary or > simply some other way to group code. I think the main reason for this is that people have to be able to type the code. I do remember the days when German keyboards didn't have brackets and braces and you had to type alt-123 to get a {. Made it real fun to program in C ... If you design a language and in IDE together (the way Smalltalk was designed back in the 1970s or maybe Visual Basic) you can use all sorts of funky characters because you can also provide a standard way to enter them. But if you expect your users to type programs in a standard text editor (even a fancy one like Emacs or Vim or VS Code), you have to restrict yourself to a character set that most people can comfortably type on their keyboards with the key mapping provided by their OS. Which for historical reasons means US-ASCII. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | h...@hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Sat, 5 Mar 2022 at 10:28, Peter J. Holzer wrote: > > On 2022-03-04 11:34:07 +1100, Chris Angelico wrote: > > On Fri, 4 Mar 2022 at 10:09, Avi Gross via Python-list > > wrote: > > > The drumbeat I keep hearing is that some people hear/see the same > > > word as implying something else. ELSE is ambiguous in the context it > > > is used. > > > > What I'm hearing is that there are, broadly speaking, two types of > > programmers [1]: > > > > 1) Those who think about "for-else" as a search tool and perfectly > > understand how it behaves > > 2) Those who have an incorrect idea about what for-else is supposed to > > do, don't understand it, and don't like it. > > 3) Those who understand what it does und don't even find it*s syntax > very confusing, yet only very rarely find it useful. > > I have probably used it a handful of times in 8 years of Python > programming. Coincidentally, I think I used it just this week - but I > can't find it any more which probably means that it was either in a > throwaway script or I have since rewritten the code. > Part of group 1. It doesn't matter how often or rarely you use the feature; there are a LOT of features of Python that I use only occasionally, if ever. But as long as you know how to use it, it's there when you need it. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-04 11:34:07 +1100, Chris Angelico wrote: > On Fri, 4 Mar 2022 at 10:09, Avi Gross via Python-list > wrote: > > The drumbeat I keep hearing is that some people hear/see the same > > word as implying something else. ELSE is ambiguous in the context it > > is used. > > What I'm hearing is that there are, broadly speaking, two types of > programmers [1]: > > 1) Those who think about "for-else" as a search tool and perfectly > understand how it behaves > 2) Those who have an incorrect idea about what for-else is supposed to > do, don't understand it, and don't like it. 3) Those who understand what it does und don't even find it*s syntax very confusing, yet only very rarely find it useful. I have probably used it a handful of times in 8 years of Python programming. Coincidentally, I think I used it just this week - but I can't find it any more which probably means that it was either in a throwaway script or I have since rewritten the code. hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | h...@hjp.at |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
Yes, Rob, I keep wondering how many decades it will take before people here understand how I make a point with an example that is not intended in any way to be complete or the way I would do it. No, I would not normally use the exception method, let alone in this case. This one practically screams for the method you suggest and iterate on a list of directories made from splitting the PATH variable. And, yes that method would likely use a for loop with a break if it is found and is a candidate for using the ELSE clause to note it has not been found. But it is not an unusual idiom these days to use exceptions in places I never dreamed of in my earlier programming languages. A common example is always testing before accidentally dividing by zero and now code that depends on throwing the right exception and dealing with it, especially if the exception happens rarely. So in situations where almost all programs are found in the first component of PATH, perhaps the exception approach is not horrible. It may even at times be done with less coding effort than other alternatives. Not my preferred way, of course. -Original Message- From: Rob Cliffe via Python-list To: python-list@python.org Sent: Fri, Mar 4, 2022 5:22 pm Subject: Re: Behavior of the for-else construct On 04/03/2022 20:52, Avi Gross via Python-list wrote: > > I have an observation about exception handling in general. Some people use > exceptions, including ones they create and throw, for a similar idea. You > might for example try to use an exception if your first attempt fails that > specifies trying the next attempt. In my example of the PATH variable, you > might use something like calling a function and giving it what you are > looking for as well as a local copy of the PATH variable content and the > exception would be to call the function again with the first component of > PATH removed until you fail with an empty PATH. Yes, this is similar to just > having a recursive function. That sounds neither readable nor efficient compared with using split() plus a loop. Maybe you mean this to be a toy, unrealistic example? > So the example tossed at us looks a bit more like this and it does run the > ELSE not because the loop is not done but because the loop never calls a > break: > > for x in range(0): > print(x) > else: > print("Finally finished!") This would be more readable with a `zeroiterations` keyword, which accurately describes both the semantics and the intent. > Which leads me right back to wondering why the sentinel approach is so bad! > > It's not that bad, but it's more convenient and readable if it can be avoided. Best wishes Rob Cliffe -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-04 14:04:48 -0600, Om Joshi wrote: > I'm not sure if anyone has mentioned it on this thread, but with > respect to your comment about adding either on.empty or a decorator, > the Django template syntax uses > > {% for x in iterator %} > {{ x }} > {% empty %} > Empty > {% endfor %} > > and this seems to work quite well and be incredibly intuitive, at > least for Django html templates. OTOH it is frequently not what you want. Take this example from the Django docs: {% for athlete in athlete_list %} {{ athlete.name }} {% empty %} Sorry, no athletes in this list. {% endfor %} If athlete_list is empty, it will produce: Sorry, no athletes in this list. which is awful typography. You don't want a list with a single item, you want that text *instead of* the list. So you would have to write {% if athlete_list %} {% for athlete in athlete_list %} {{ athlete.name }} {% empty %} {% else %} Sorry, no athletes in this list. {%endif %} anyway. hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | h...@hjp.at |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-04 08:38:52 -0600, Tim Chase wrote: > On 2022-03-04 11:55, Chris Angelico wrote: > > In MS-DOS, it was perfectly possible to have spaces in file names > > DOS didn't allow space (0x20) in filenames unless you hacked it by > hex-editing your filesystem (which I may have done a couple times). > However it did allow you to use 0xFF in filenames which *appeared* as > a space in most character-sets. I may be misremembering (it's been 30+ years), but I seem to remember that a simple fopen("with space.txt", "w") in Turbo C would create a file with a space (actually called "WITH SPA.TXT", because upper case only and 8+3). It was a bad idea to do this, though, because there was no way to manipulate such a file from command.com (You'd have to write another C program). hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | h...@hjp.at |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-04 00:38:22 +, Avi Gross via Python-list wrote: > I have seen major struggles to get other character sets into > languages. Any new language typically should have this built in from > scratch and should consider adding non-ASCII characters into the mix. > Mathematicians often use lots of weird braces/brackets as an example > while normal programs are limited to [{( and maybe < and their > counterparts. This leads to odd Python behavior (other languages too) > where symbols are re-used ad nauseam. { can mean set or dictionary or > simply some other way to group code. I think the main reason for this is that people have to be able to type the code. I do remember the days when German keyboards didn't have brackets and braces and you had to type alt-123 to get a {. Made it real fun to program in C ... If you design a language and in IDE together (the way Smalltalk was designed back in the 1970s or maybe Visual Basic) you can use all sorts of funky characters because you can also provide a standard way to enter them. But if you expect your users to type programs in a standard text editor (even a fancy one like Emacs or Vim or VS Code), you have to restrict yourself to a character set that most people can comfortably type on their keyboards with the key mapping provided by their OS. Which for historical reasons means US-ASCII. hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | h...@hjp.at |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 04/03/2022 20:52, Avi Gross via Python-list wrote: I have an observation about exception handling in general. Some people use exceptions, including ones they create and throw, for a similar idea. You might for example try to use an exception if your first attempt fails that specifies trying the next attempt. In my example of the PATH variable, you might use something like calling a function and giving it what you are looking for as well as a local copy of the PATH variable content and the exception would be to call the function again with the first component of PATH removed until you fail with an empty PATH. Yes, this is similar to just having a recursive function. That sounds neither readable nor efficient compared with using split() plus a loop. Maybe you mean this to be a toy, unrealistic example? So the example tossed at us looks a bit more like this and it does run the ELSE not because the loop is not done but because the loop never calls a break: for x in range(0): print(x) else: print("Finally finished!") This would be more readable with a `zeroiterations` keyword, which accurately describes both the semantics and the intent. Which leads me right back to wondering why the sentinel approach is so bad! It's not that bad, but it's more convenient and readable if it can be avoided. Best wishes Rob Cliffe -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
Om (unless your first name is Joshi), Yes, your example captures some of my intent. I have not studied Django but your example suggests it uses special notation using a sort of set of braces like I have talked about "{%" and "%}" that allows freedom in using what might otherwise need keywords. Anything between braces can be an extension of the language in a context where users do not put their own variable names. But again, any language defined can be set up to do things their own way. In Python, I believe the contents of a loop are not examined at all if skipped so searching in it for some clause of what to do if empty is not doable. The ELSE clause is a way to get the attention if there has been no break. I would not be shocked if some language has a FOR command return a value such as the number of iterations if run and something like None if not and allows something like: result = for ... That might return 0 or None if it was part of the language but it is not. Avi (my current first name) -Original Message- From: Om Joshi To: Avi Gross Cc: python-list Sent: Fri, Mar 4, 2022 3:04 pm Subject: Re: Behavior of the for-else construct I'm not sure if anyone has mentioned it on this thread, but with respect to your comment about adding either on.empty or a decorator, the Django template syntax uses {% for x in iterator %} {{ x }} {% empty %} Empty {% endfor %} and this seems to work quite well and be incredibly intuitive, at least for Django html templates. I took a look and it has other enhancements like a way to know when you are in the last iteration of the loop. {% if forloop.last %} ... {% endif %} And also for the first item using forloop.first and a generalized counter in forloop.counter .. On Fri, 04 Mar 2022 13:45:21 -0600 Avi Gross via Python-list wrote > {NOTE, after some diversion, this long message does revert a bit to the > topic.} > > Ah, Chris, the games we played when we were young and relatively immature! > > Has anyone else played with embedding "escape sequences" or other gimmicks > in unexpected places like filenames so that on the right terminals, such as > the VT100, it displayed oddly or was hard to open or delete as what showed > was not quite the underlying representation? > > The main reason for the restrictions in olden days was cost. Everything was > so costly including storage/memory and CPU time. Clearly it is a lot easier > to have fixed-length filenames that fit into say 16 bytes, or storing > multiple flags about file permissions as single bits, even if it meant lots > of bit-twiddling or using masks to retrieve their values. We think nothing > of creating structures that have many others embedded in them as attributes > or function calls that allow a hundred optional arguments so that the > function spends much of the time used just figuring out what was set before > doing whatever calculation is required to fulfill the request. > > I was reading a novel recently (Jack Reacher Series) where the main > character is noticing how much technology has changed as they have been > ignoring it for a decade or so. Everything seems to be coming up faster. My > view was that if something seems ten times as fast as it was, it also > probably is doing a hundred or ten thousand times as much to get that > result. The real speed changes are often counterbalanced by expecting to do > more. A web page served may display a screen of text but to transmit it may > include not just lots of padding in the HTML, but have all kinds of code > such as in Java or JavaScript or lots of back and forth with the server to > keep something like a graph displayed being refreshed ... > > So back to filenames, the concept of having to search for long filenames > that may not even be stored sequentially in large blocks that can be read > (ahead) efficiently, may have seemed to be so illogical as not to be > considered. So given that the shorter ones were not allowed to have embedded > spaces, it made sense to treat them like tokens that could be broken up at > whitespace. As mentioned, languages (or other programs) would often parse a > command line and create something like this for the main program in C with > suitable version in Python and other languages: > > main(int argc, char *argv[]) > > The code variations on the above do suppose that something has already > parsed the command line that invoked them and partitioned it properly into > individual strings placed in an array of such strings and also returned how > many arguments it saw. Users invoking the program needed to be careful such > as using double quotes around anything with embedded spaces, where allowed. > > But like m
Re: Behavior of the for-else construct
On 03/03/2022 19.54, Rob Cliffe wrote: On 04/03/2022 01:44, Ethan Furman wrote: On 3/3/22 5:32 PM, Rob Cliffe via Python-list wrote: > There are three types of programmer: those that can count, and those that can't. Actually, there are 10 types of programmer: those that can count in binary, and those that can't. 1, 10, many. No problem. Ah, a George Gamow fan. -- Michael F. Stemper Psalm 82:3-4 -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Sat, 5 Mar 2022 at 07:52, Avi Gross wrote: > > Chris, > > My example was precisely what to do when it is an empty closet: Does it correctly handle a closet with shirts in it, though? There's not a lot of point demonstrating an alternate use for the "else" clause when it is *absolutely identical* to simply placing two loops one after another. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
Chris, My example was precisely what to do when it is an empty closet: > closet = [] > > attic = ["Costumes", "Sheets", "Shirts" ] > > for item in closet: > print(item) > if item == "Shirts" : print("FOUND in closet!!") > else: > for item in attic: > print(item) > if item == "Shirts" : print("FOUND in attic!!") Of course, for a more complete program, there is a reason to break out of either loop if you find what you are looking for. I was illustrating an alternate use in what I agree is a very incomplete example as it was meant only to illustrate one point. And my example may be implemented very differently if you need to search in dozens of places. Consider the ubiquitous PATH variable. Many programs search in one after another of the components for something like a filename. Doing that with a series of nested FOR loops with each one nested in the ELSE of the previous one might be a tad ridiculous! I have an observation about exception handling in general. Some people use exceptions, including ones they create and throw, for a similar idea. You might for example try to use an exception if your first attempt fails that specifies trying the next attempt. In my example of the PATH variable, you might use something like calling a function and giving it what you are looking for as well as a local copy of the PATH variable content and the exception would be to call the function again with the first component of PATH removed until you fail with an empty PATH. Yes, this is similar to just having a recursive function. But I am hoping to get across my view that there are many ways to do things but sometimes a new feature is useful because it is more direct or other reasons. in the case we are discussing, what are the scope issues in: eye = 1 for eye in ... : pass else: eye = None It looks like all references to eye refer to the same object. Some other methods we have touched on (or others may bring up) may result in different results as variables may be in other name spaces. My understanding of the PYTHON-only implementation of the above is something like this. Imagine a FOR loop that does not ignore the contents no matter what and the body looks like: if SOMETHING_IS_BEING_DONE: main code processing eye sequentially else: # only used if nothing is being done normally eye = None The above made-up scenario would allow the external ELSE to be seen as the implied else to an if that tests if the loop was actually entered. Of course it is not implemented this way, but it would show why variable eye is in the same scope in the several parts. Once you play with exceptions and other functions, this may change. The alternative suggestions about ELSE being associated confuse this issue so I want to be clear. The main meaning of the ELSE clause does not sound quite like this. It is actually about what to do with a loop that terminates normally, as I think Chris pointed out. This example finishes the loop normally and then does the ELSE: for x in range(6): print(x) else: print("Finally finished!") The following example is similar but quits early: for x in range(6): if x < 4: print(x) else: break else: print("Finally finished!") The (second) else clause is not run. So the example tossed at us looks a bit more like this and it does run the ELSE not because the loop is not done but because the loop never calls a break: for x in range(0): print(x) else: print("Finally finished!") So unless I am missing something, the code would destroy the last value of the variable even in a valid case when it looks like: for aye in range(0): pass else: aye = None I mean if you used range(5) you would expect the value of aye==4 after the loop. The above loop would leave it as aye==None which keeps it from being undefined. To decide if the loop ran at all would thus require further code such as: if aye == None: ... Which leads me right back to wondering why the sentinel approach is so bad! -Original Message- From: Chris Angelico To: python-list@python.org Sent: Fri, Mar 4, 2022 12:47 pm Subject: Re: Behavior of the for-else construct On Sat, 5 Mar 2022 at 03:44, Avi Gross via Python-list wrote: > > Dieter, > > Your use is creative albeit it is not "needed" since all it does is make sure > your variable is initialized to something, specifically None. > > So would this not do the same thing? > > eye = None > > for eye in range(0): > print(eye) > > eye > > If I understand it, your example depends on a variable that is not yet > initialized to be used in a loop and retain the last value after the loop. > You then set it to None if it is not used as the loop is skipped. Others have > shown an e
Re: Behavior of the for-else construct
On 2022-03-04 at 11:14:29 -0500, Dennis Lee Bieber wrote: > Try to tell the difference between > > afileand > afile > > when doing a directory listing. Easy: log in over a 110 baud modem, where the characters take almost as much time as the beep. ;-) -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
for a decorator concept like: > > @on.empty(...) > for eye in range(0): > pass > > I am ending with a reminder. NOTHING I am writing here is meant to be taken > seriously but merely as part of a well-intentioned debate to share ideas and > not to win or lose but learn. Python is more than a language but also has > aspects of a culture and we sometimes talk about whether something has a > pythonic flavor or is pythonic versus translating it literally from a > language like C rather than using the ideas common in python. The method > chosen to implement the ELSE clause here may well be Pythonic and some of my > attempts to show other ways may well not be. I am not one of those that find > the current implementation to be the wrong one and will happily use it when > I have code that can be done well that way. I am just discussing the issue > and wider ones. Languages have an amazing variety of designs that fascinate > me. > > > > -Original Message- > From: Chris Angelico > To: python-list@python.org > Sent: Fri, Mar 4, 2022 12:46 pm > Subject: Re: Behavior of the for-else construct > > > On Sat, 5 Mar 2022 at 02:02, Tim Chase > wrote: > > > > On 2022-03-04 11:55, Chris Angelico wrote: > > > In MS-DOS, it was perfectly possible to have spaces in file names > > > > DOS didn't allow space (0x20) in filenames unless you hacked it by > > hex-editing your filesystem (which I may have done a couple times). > > However it did allow you to use 0xFF in filenames which *appeared* as > > a space in most character-sets. > > Hmm, I'm not sure which APIs worked which way, but I do believe that I > messed something up at one point and made a file with an included > space (not FF, an actual 20) in it. Maybe it's something to do with > the (ancient) FCB-based calls. It was tricky to get rid of that file, > though I think it turned out that it could be removed by globbing, > putting a question mark where the space was. > > (Of course, internally, MS-DOS considered that the base name was > padded to eight with spaces, and the extension padded to three with > spaces, so "READ.ME" would be "READ\x20\x20\x20\x20ME\x20", but that > doesn't count, since anything that enumerates the contents of a > directory would translate that into the way humans think of it.) > > > I may have caused a mild bit of consternation in school computer labs > > doing this. ;-) > > Nice :) > > > > Windows forbade a bunch of characters in file names > > > > Both DOS and Windows also had certain reserved filenames > > > > https://www.howtogeek.com/fyi/windows-10-still-wont-let-you-use-these-file-names-reserved-in-1974/ > > > > that could cause issues if passed to programs. > > Yup. All because, way back in the day, they didn't want to demand the > colon. If you actually *want* to use the printer device, for instance, > you could get a hard copy of a directory listing like this: > > DIR >LPT1: > > and it's perfectly clear that you don't want to create a file called > "LPT1", you want to send it to the printer. But noo it had to be > that you could just write "LPT1" and it would go to the printer. > > > To this day, if you poke around on microsoft.com and change random > > bits of URLs to include one of those reserved filenames in the GET > > path, you'll often trigger a 5xx error rather than a 404 that you > > receive with random jibberish in the same place. > > > > https://microsoft.com/…/asdfjkl → 404 > > https://microsoft.com/…/lpt1 → 5xx > > https://microsoft.com/…/asdfjkl/some/path → 404 > > https://microsoft.com/…/lpt1/some/path → 5xx > > > > Just in case you aspire to stir up some trouble. > > > > In theory, file system based URLs could be parsed such that, if you > ever hit one of those, it returns "Directory not found". In > practice... apparently they didn't do that. > > As a side point, I've been increasingly avoiding any sort of system > whereby I take anything from the user and hand it to the file system. > The logic is usually more like: > > If path matches "/static/%s": > 1) Get a full directory listing of the declared static-files directory > 2) Search that for the token given > 3) If not found, return 404 > 4) Return the contents of the file, with cache markers > > Since Windows will never return "lpt1" in that directory listing, I > would simply never find it, never even try to open it. This MIGHT be > an issue with something that accepts file *uploads*, but I've been > getting paranoid about those too, so, uhh... my file upload system now > creates URLs that look like this: > > https://sikorsky.rosuav.com/static/upload-49497888-6bede802d13c8d2f7b92ca9fac7c > > That was uploaded as "pie.gif" but stored on the file system as > ~/stillebot/httpstatic/uploads/49497888-6bede802d13c8d2f7b92ca9fac7c > with some metadata stored elsewhere about the user-specified file > name. So hey, if you were to try to upload a file that had an NTFS > invalid character in it, I wouldn't even notice. > > Maybe I'm *too* paranoid, but at least I don't have to worry about > file system attacks. > > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > > > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
t. You may end up having to make people do more than they would prefer such as quoting all variable names even if they do not "need" it. Wouldn't it be nice to be able to name a variable 1time@least if you felt like it? Many people have passwords like that. I think the answer is NO, not if it meant quoting every variable because there was no longer any reasonable way to parse programs. The issue that started the discussion was different but in a sense similar. If you want to extend the functionality of a "for" loop in one of many possible ways, how do you design a way to specify it so it can both be unambiguously parsed and implemented while at the same time making sense to humans reading it and interpreting it using their human language skills. I happen to think this is even harder for some who speak in languages other than English and have to program in languages loosely based on English. I am happy that I seem to think in English now but I was seven when I first encountered it after thinking in others. People who program do not all speak English or are more fluent in other languages. T may may be used to other word orders for example. They may move verbs to the end of a sentence or place adjectives or other modifiers after versus before a word and forget about all the other games played where the same word means something completely different. To them ELSE may either mean nothing or the phrase IF ... ELSE may be said differently or adding a clause after the construct is not seen as natural. So was this way of doing FOR ... ELSE the only or even best way, is what some of this debate is about. I am thinking of a function in some languages that lets you specify what should happen in a later circumstance. In a language like R, you can specify one or more instances of on.exit(...) that are not run immediately. Each one can replace the commands in the previous one or add on to it. When the function they are defined in exits for any reason, it pauses to run any uncleared such commands. Clearly this works better if a language has a way to defer evaluation of code so there are no side effects. So consider the suggestion of code that should be run if you have a loop and you break out of it. Could you design an alternate way to handle that other than adding an ELSE clause after the loop? Clearly you could simply add a function called on.break() that can be used as described but only within the body of that loop. It might be something that can be set and unset as needed and when the loop is exited, the program implicitly checks to see if any code has been dynamically set and executes it. This clearly is not necessarily a good way or better way, but is an example of how you can implement something without using any key words. No need to think about forcing the use of ELSE versus a new keyword that may conflict with existing code. Yes, the name on.break may conflict but that is trivially handled in Python by invoking it with a full name that includes what module it is in or by creating an alias. So what about considering an alternate approach that does handle a for loop that does nothing? Would it create huge incompatibilities for something like: for eye in range(0), on.empty=... : pass In some languages, arbitrary additional arguments are allowed, and if not understood, are ignored. Python does not allow anything like the above. And in this case, the entire body of the for loop is never evaluated so no gimmicks inside the body are possible. A gimmick before it might work and I even wonder if there is room here for a decorator concept like: @on.empty(...) for eye in range(0): pass I am ending with a reminder. NOTHING I am writing here is meant to be taken seriously but merely as part of a well-intentioned debate to share ideas and not to win or lose but learn. Python is more than a language but also has aspects of a culture and we sometimes talk about whether something has a pythonic flavor or is pythonic versus translating it literally from a language like C rather than using the ideas common in python. The method chosen to implement the ELSE clause here may well be Pythonic and some of my attempts to show other ways may well not be. I am not one of those that find the current implementation to be the wrong one and will happily use it when I have code that can be done well that way. I am just discussing the issue and wider ones. Languages have an amazing variety of designs that fascinate me. -Original Message- From: Chris Angelico To: python-list@python.org Sent: Fri, Mar 4, 2022 12:46 pm Subject: Re: Behavior of the for-else construct On Sat, 5 Mar 2022 at 02:02, Tim Chase wrote: > > On 2022-03-04 11:55, Chris Angelico wrote: > > In MS-DOS, it was perfectly possible to have spaces in file names > > DOS didn't allow space (0x20) in filenames unless you hacked it by > hex-editing your fil
Re: Behavior of the for-else construct
On Fri, 4 Mar 2022 08:38:52 -0600, Tim Chase declaimed the following: >DOS didn't allow space (0x20) in filenames unless you hacked it by >hex-editing your filesystem (which I may have done a couple times). >However it did allow you to use 0xFF in filenames which *appeared* as >a space in most character-sets. > >I may have caused a mild bit of consternation in school computer labs >doing this. ;-) > Xerox CP/V actually allowed to be embedded in file names... Try to tell the difference between afile and afile when doing a directory listing. {Though the BASIC interpreter gave it away -- doing a directory from within the interpreter resulted in a hex representation of names with non-graphic characters... In EBCDIC of course} -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Sat, 5 Mar 2022 at 03:44, Avi Gross via Python-list wrote: > > Dieter, > > Your use is creative albeit it is not "needed" since all it does is make sure > your variable is initialized to something, specifically None. > > So would this not do the same thing? > > eye = None > > for eye in range(0): > print(eye) > > eye > > If I understand it, your example depends on a variable that is not yet > initialized to be used in a loop and retain the last value after the loop. > You then set it to None if it is not used as the loop is skipped. Others have > shown an example similar to the above of using a sentinel that lets you know > if the loop is skipped. > > Of course, there are some advantages in making it clear by doing it you way > that the loop (for example if copied and used elsewhere) needs to include the > else statement as an integral part. > > I would like to suggest a slight modification to the above as in if you are > searching for something in either seq1 and if not found in seq2. Call it > looking for your green shirt in the closet and if not found, looking in the > attic. Would this code make sense as such a use in several ways? In English, > look here first and if there is NOTHING there, look in the second place? > > closet = [] > > attic = ["Costumes", "Sheets", "Shirts" ] > > for item in closet: > print(item) > if item == "Shirts" : print("FOUND in closet!!") > else: > for item in attic: > print(item) > if item == "Shirts" : print("FOUND in attic!!") > > Yes, as discussed, you could do an IF statement to check if closet is empty > but for iterators, it gets ... > Make sure you 'break' after finding it. Otherwise, you'll keep searching the rest of your closet, and then still go on to search your attic. The "else:" clause doesn't help you here unless that break is present. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Sat, 5 Mar 2022 at 02:02, Tim Chase wrote: > > On 2022-03-04 11:55, Chris Angelico wrote: > > In MS-DOS, it was perfectly possible to have spaces in file names > > DOS didn't allow space (0x20) in filenames unless you hacked it by > hex-editing your filesystem (which I may have done a couple times). > However it did allow you to use 0xFF in filenames which *appeared* as > a space in most character-sets. Hmm, I'm not sure which APIs worked which way, but I do believe that I messed something up at one point and made a file with an included space (not FF, an actual 20) in it. Maybe it's something to do with the (ancient) FCB-based calls. It was tricky to get rid of that file, though I think it turned out that it could be removed by globbing, putting a question mark where the space was. (Of course, internally, MS-DOS considered that the base name was padded to eight with spaces, and the extension padded to three with spaces, so "READ.ME" would be "READ\x20\x20\x20\x20ME\x20", but that doesn't count, since anything that enumerates the contents of a directory would translate that into the way humans think of it.) > I may have caused a mild bit of consternation in school computer labs > doing this. ;-) Nice :) > > Windows forbade a bunch of characters in file names > > Both DOS and Windows also had certain reserved filenames > > https://www.howtogeek.com/fyi/windows-10-still-wont-let-you-use-these-file-names-reserved-in-1974/ > > that could cause issues if passed to programs. Yup. All because, way back in the day, they didn't want to demand the colon. If you actually *want* to use the printer device, for instance, you could get a hard copy of a directory listing like this: DIR >LPT1: and it's perfectly clear that you don't want to create a file called "LPT1", you want to send it to the printer. But noo it had to be that you could just write "LPT1" and it would go to the printer. > To this day, if you poke around on microsoft.com and change random > bits of URLs to include one of those reserved filenames in the GET > path, you'll often trigger a 5xx error rather than a 404 that you > receive with random jibberish in the same place. > > https://microsoft.com/…/asdfjkl → 404 > https://microsoft.com/…/lpt1 → 5xx > https://microsoft.com/…/asdfjkl/some/path → 404 > https://microsoft.com/…/lpt1/some/path → 5xx > > Just in case you aspire to stir up some trouble. > In theory, file system based URLs could be parsed such that, if you ever hit one of those, it returns "Directory not found". In practice... apparently they didn't do that. As a side point, I've been increasingly avoiding any sort of system whereby I take anything from the user and hand it to the file system. The logic is usually more like: If path matches "/static/%s": 1) Get a full directory listing of the declared static-files directory 2) Search that for the token given 3) If not found, return 404 4) Return the contents of the file, with cache markers Since Windows will never return "lpt1" in that directory listing, I would simply never find it, never even try to open it. This MIGHT be an issue with something that accepts file *uploads*, but I've been getting paranoid about those too, so, uhh... my file upload system now creates URLs that look like this: https://sikorsky.rosuav.com/static/upload-49497888-6bede802d13c8d2f7b92ca9fac7c That was uploaded as "pie.gif" but stored on the file system as ~/stillebot/httpstatic/uploads/49497888-6bede802d13c8d2f7b92ca9fac7c with some metadata stored elsewhere about the user-specified file name. So hey, if you were to try to upload a file that had an NTFS invalid character in it, I wouldn't even notice. Maybe I'm *too* paranoid, but at least I don't have to worry about file system attacks. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
Avi Gross wrote at 2022-3-4 16:43 +: >Your use is creative albeit it is not "needed" since all it does is make sure >your variable is initialized to something, specifically None. > >So would this not do the same thing? > > eye = None > > for eye in range(0): > print(eye) > > eye It would. But, the `for` construct's main purpose is often to determine a value for the loop variable and in this case, I like that it itself can ensure that it gets a value. -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
Dieter, Your use is creative albeit it is not "needed" since all it does is make sure your variable is initialized to something, specifically None. So would this not do the same thing? eye = None for eye in range(0): print(eye) eye If I understand it, your example depends on a variable that is not yet initialized to be used in a loop and retain the last value after the loop. You then set it to None if it is not used as the loop is skipped. Others have shown an example similar to the above of using a sentinel that lets you know if the loop is skipped. Of course, there are some advantages in making it clear by doing it you way that the loop (for example if copied and used elsewhere) needs to include the else statement as an integral part. I would like to suggest a slight modification to the above as in if you are searching for something in either seq1 and if not found in seq2. Call it looking for your green shirt in the closet and if not found, looking in the attic. Would this code make sense as such a use in several ways? In English, look here first and if there is NOTHING there, look in the second place? closet = [] attic = ["Costumes", "Sheets", "Shirts" ] for item in closet: print(item) if item == "Shirts" : print("FOUND in closet!!") else: for item in attic: print(item) if item == "Shirts" : print("FOUND in attic!!") Yes, as discussed, you could do an IF statement to check if closet is empty but for iterators, it gets ... -Original Message- From: Dieter Maurer To: Rob Cliffe Cc: python-list@python.org Sent: Fri, Mar 4, 2022 2:12 am Subject: Re: Behavior of the for-else construct Rob Cliffe wrote at 2022-3-4 00:13 +: >I find it so hard to remember what `for ... else` means that on the very >few occasions I have used it, I ALWAYS put a comment alongside/below the >`else` to remind myself (and anyone else unfortunate enough to read my >code) what triggers it, e.g. > > for item in search_list: > ... > ... break > else: # if no item in search_list matched the criteria > >You get the idea. >If I really want to remember what this construct means, I remind myself >that `else` here really means `no break`. Would have been better if it >had been spelt `nobreak` or similar in the first place. One of my use cases for `for - else` does not involve a `break`: the initialization of the loop variable when the sequence is empty. It is demonstrated by the following transscript: ```pycon >>> for i in range(0): ... pass ... >>> i Traceback (most recent call last): File "", line 1, in NameError: name 'i' is not defined >>> for i in range(0): ... pass ... else: i = None ... >>> i >>> ``` For this use case, `else` is perfectly named. -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-04 11:55, Chris Angelico wrote: > In MS-DOS, it was perfectly possible to have spaces in file names DOS didn't allow space (0x20) in filenames unless you hacked it by hex-editing your filesystem (which I may have done a couple times). However it did allow you to use 0xFF in filenames which *appeared* as a space in most character-sets. I may have caused a mild bit of consternation in school computer labs doing this. ;-) > Windows forbade a bunch of characters in file names Both DOS and Windows also had certain reserved filenames https://www.howtogeek.com/fyi/windows-10-still-wont-let-you-use-these-file-names-reserved-in-1974/ that could cause issues if passed to programs. To this day, if you poke around on microsoft.com and change random bits of URLs to include one of those reserved filenames in the GET path, you'll often trigger a 5xx error rather than a 404 that you receive with random jibberish in the same place. https://microsoft.com/…/asdfjkl → 404 https://microsoft.com/…/lpt1 → 5xx https://microsoft.com/…/asdfjkl/some/path → 404 https://microsoft.com/…/lpt1/some/path → 5xx Just in case you aspire to stir up some trouble. -tkc -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Fri, 4 Mar 2022 at 21:02, gene heskett wrote: > That makes the logic work, but who then cleans up the trash on the stack. > Thats a memory leak. > Not sure I follow? ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Friday, 4 March 2022 02:18:51 EST Chris Angelico wrote: > On Fri, 4 Mar 2022 at 18:13, Dieter Maurer wrote: > > Rob Cliffe wrote at 2022-3-4 00:13 +: > > >I find it so hard to remember what `for ... else` means that on the > > >very few occasions I have used it, I ALWAYS put a comment > > >alongside/below the `else` to remind myself (and anyone else > > >unfortunate enough to read my code) what triggers it, e.g. > > > > > > for item in search_list: > > > ... > > > ... break > > > > > > else: # if no item in search_list matched the criteria > > > > > >You get the idea. > > >If I really want to remember what this construct means, I remind > > >myself that `else` here really means `no break`. Would have been > > >better if it had been spelt `nobreak` or similar in the first > > >place. > > > > One of my use cases for `for - else` does not involve a `break`: > > the initialization of the loop variable when the sequence is empty. > > It is demonstrated by the following transscript: > > > > ```pycon > > > > >>> for i in range(0): > > ... pass > > ... > > > > >>> i > > > > Traceback (most recent call last): > > File "", line 1, in > > > > NameError: name 'i' is not defined > > > > >>> for i in range(0): > > ... pass > > ... else: i = None > > ... > > > > >>> i > > > > ``` > > > > For this use case, `else` is perfectly named. > > What's the point of this? Why not just put "i = None" after the loop? > That makes the logic work, but who then cleans up the trash on the stack. Thats a memory leak. > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > . Cheers, Gene Heskett. -- "There are four boxes to be used in defense of liberty: soap, ballot, jury, and ammo. Please use in that order." -Ed Howdershelt (Author, 1940) If we desire respect for the law, we must first make the law respectable. - Louis D. Brandeis -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
Op 4/03/2022 om 1:43 schreef Chris Angelico: Think of it like this: for item in search_list: if condition: pass else: print("Condition not true for this item") for item in search_list: if condition: break else: print("Condition not true for any item") There's a parallel here. Since a for-else loop is basically useless without an if-break construct inside it, the else clause can be thought of as the else on a massive if/elif chain: if stuff[0].is_good: print("This item is good", stuff[0]) elif stuff[1].is_good: print("This item is good", stuff[1]) ... ... elif stuff[n].is_good: print("This item is good", stuff[n]) else: print("All items are bad") As a loop, this looks like this: for item in stuff: if item.is_good: print("This item is good", item) break else: print("All items are bad") The else is attached to the for so that it compasses ALL the if statements, but it's still broadly saying "do this when we don't hit the 'if' condition". Whether that's a sufficient mnemonic, I don't know [...] Certainly not for me. It could work for the specific use case you mention, but nothing in the definition restricts it to be used for that use case. As Rob Cliffe says in one of his posts, a for-loop can be terminated with "break" for many conceptually different reasons. A mnemonic that only works for one specific use case, even if it's the most used one, doesn't work as a mnemonic for the general concept for me. [...], but it doesn't really matter; the construct is useful to those of us who want it, and if other people ignore it, that's fine. Nobody ever said you had to use or understand every single feature of the language you're using. True, still, I agree with people who think nobreak would have been better because it better conveys the intention. IIRC Raymond Hettinger once said something like that too, so I'm in good company I guess. -- "Honest criticism is hard to take, particularly from a relative, a friend, an acquaintance, or a stranger." -- Franklin P. Jones -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
Op 4/03/2022 om 8:18 schreef Chris Angelico: On Fri, 4 Mar 2022 at 18:13, Dieter Maurer wrote: > One of my use cases for `for - else` does not involve a `break`: > the initialization of the loop variable when the sequence is empty. > It is demonstrated by the following transscript: > > ```pycon > >>> for i in range(0): > ... pass > ... > >>> i > Traceback (most recent call last): > File "", line 1, in > NameError: name 'i' is not defined > >>> for i in range(0): > ... pass > ... else: i = None > ... > >>> i > >>> > ``` > > For this use case, `else` is perfectly named. What's the point of this? Why not just put "i = None" after the loop? As I understand it: range(0) is just a (bad) example, it's actually about any arbitrary iterable. You don't know in advance if it's empty or not, and you want i to be initialized in all cases. (I don't think I have ever encountered that situation.) You could easily solve this by placing "i = None" before the loop, but I guess in situations where you want to initialize i with the result of an expensive operation Dieter's method could be a reasonable solution. This would actually be a good use case for computermaster360's proposal. -- "Honest criticism is hard to take, particularly from a relative, a friend, an acquaintance, or a stranger." -- Franklin P. Jones -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Fri, 4 Mar 2022 at 18:13, Dieter Maurer wrote: > > Rob Cliffe wrote at 2022-3-4 00:13 +: > >I find it so hard to remember what `for ... else` means that on the very > >few occasions I have used it, I ALWAYS put a comment alongside/below the > >`else` to remind myself (and anyone else unfortunate enough to read my > >code) what triggers it, e.g. > > > > for item in search_list: > > ... > > ... break > > else: # if no item in search_list matched the criteria > > > >You get the idea. > >If I really want to remember what this construct means, I remind myself > >that `else` here really means `no break`. Would have been better if it > >had been spelt `nobreak` or similar in the first place. > > One of my use cases for `for - else` does not involve a `break`: > the initialization of the loop variable when the sequence is empty. > It is demonstrated by the following transscript: > > ```pycon > >>> for i in range(0): > ... pass > ... > >>> i > Traceback (most recent call last): > File "", line 1, in > NameError: name 'i' is not defined > >>> for i in range(0): > ... pass > ... else: i = None > ... > >>> i > >>> > ``` > > For this use case, `else` is perfectly named. What's the point of this? Why not just put "i = None" after the loop? ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
Rob Cliffe wrote at 2022-3-4 00:13 +: >I find it so hard to remember what `for ... else` means that on the very >few occasions I have used it, I ALWAYS put a comment alongside/below the >`else` to remind myself (and anyone else unfortunate enough to read my >code) what triggers it, e.g. > > for item in search_list: > ... > ... break > else: # if no item in search_list matched the criteria > >You get the idea. >If I really want to remember what this construct means, I remind myself >that `else` here really means `no break`. Would have been better if it >had been spelt `nobreak` or similar in the first place. One of my use cases for `for - else` does not involve a `break`: the initialization of the loop variable when the sequence is empty. It is demonstrated by the following transscript: ```pycon >>> for i in range(0): ... pass ... >>> i Traceback (most recent call last): File "", line 1, in NameError: name 'i' is not defined >>> for i in range(0): ... pass ... else: i = None ... >>> i >>> ``` For this use case, `else` is perfectly named. -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Fri, 4 Mar 2022 at 14:37, Avi Gross via Python-list wrote: > > That is one way to look at it, Jach. Of course, a particular loop may have > multiple break statements each meaning something else. The current > implementation makes all of them jump to the same ELSE statement so in one > sense, I consider the ELSE to be associated with the loop as a whole. > Sometimes the loop may not even have a break statement and yet the dangling > ELSE seems to be accepted anyway. > > Some languages allow you to break out of deeply nested loops by jumping up > two or more levels, perhaps to a label and are more of a goto. I shudder to > think how that would work if each loop had an ELSE dangling. > It would happen exactly the same way. I don't know why you're so afraid of the else clause. It's simply part of the loop body, and if you break out of the loop body, you skip it. If Python had a way to break out of multiple loop bodies at once, it would skip the else clauses of any that you break out of. This is not complicated. You can argue that it could be better named (but honestly, I'm not a fan of any of the other proposed names either), but the concept, at its heart, is a simple one. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
That is one way to look at it, Jach. Of course, a particular loop may have multiple break statements each meaning something else. The current implementation makes all of them jump to the same ELSE statement so in one sense, I consider the ELSE to be associated with the loop as a whole. Sometimes the loop may not even have a break statement and yet the dangling ELSE seems to be accepted anyway. Some languages allow you to break out of deeply nested loops by jumping up two or more levels, perhaps to a label and are more of a goto. I shudder to think how that would work if each loop had an ELSE dangling. -Original Message- From: Jach Feng To: python-list@python.org Sent: Thu, Mar 3, 2022 9:22 pm Subject: Re: Behavior of the for-else construct I never feel confused by "else" because I always think it in "break...else", not "for...else". For those who always think in "for...else" deserves this confusion and it can't be just escaped by replacing with another magic word such as "then" or "finally" etc:-) --Jach -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Fri, 4 Mar 2022 at 14:05, Avi Gross via Python-list wrote: > To answer something Chris said and was also mentioned here, I do not consider > language design to be easy let alone implementing it. Not at all. BUT I think > some changes can be straightforward. Having a symbol like a curly brace mean > three new things may be tough to implement. Allowing a new symbol in an > expanded set of characters seems more straightforward. > > Consider an arrow symbol → pointing to the right and another pointing the > other way. Could we add the symbol to the language as a single character, > albeit implemented using multiple bytes? If my editor let me insert the darn > thing, it might then be a reasonable use for some construct in the language > unique and new. Maybe the language would use the notation to hold objects > holding a set and not confuse the notations for sets and dictionaries as > Python ended up doing. (Yes, I know it is NOT confusing in some ways as one > holds key:value pairs and the other just value, but making an empty set now > requires the notation of set() while an empty dictionary is {} right? > > So how hard is it for a newly designed language to recognize any use of one > arrow and expect everything up to the next arrow (pointing back) to be the > contents of a set? It sounds a tad easier than now when Python interpreters > have to pause when they see an open bracket and read what follows to see if > everything beyond uses dictionary notation before it decides. > > But NO, I am not volunteering to do any of that. That is exactly why (well, one of the reasons why) I recommended going the whole way and designing a language in full. You will know exactly how hard it actually is. In fact, "pause when they see an open bracket" is the least of your worries :) ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
Rob, I consider my comments in code I write to be a (silent) part of the code, or worse, some code I commented out but want to be able to look at. I often have code like: # NOTE you can turn on one of the following that applies to your situation # and comment out the others but leave them in place. FILENAME = "C: ..." #FILENAME = "I: ... The second line is uncommented if this is run on another machine where the file is on the I: drive. Often code I write is sent to someone who has to make it work on their machine or selectively has regions turned off. # Decide if the next section should be run by selecting the line that represents your needed. NORMALIZE = True # NORMALIZE = False if (NORMALIZE): ... In cases like the above, which are not the majority of how I use comments, keeping it as I defined it makes sense even if some of the commented code is not running. It makes it easier to make customizations. I often have requests for example to read in a .CSV and depending on the situation, make multiple transformations to it that can include removing columns or filtering out rows, normalizing one or more columns, dealing with outliers beyond some designated level, creating new derived columns based on existing ones, or a Boolean reflecting some complex condition, or grouping it some way or merging it with other data and so on. If writing for myself, I might do it all in one pipeline. But if writing it for someone who plays games and tries this versus that, then something like the above, with suitable comments, lets them experiment by turning sections on and off and other forms of customization. I consider the presence of comments a serious part of what i deliver. Yes, the interpreter (and sometimes compiler) strips them but leaving them in the source file does not strike me as expensive. Once removed, I consider the person who did it suspect and am less inclined to work with them. Consider code with an embedded copyright of some sort (or apparently GNU has a copyleft) and whether it is valid to separate that from the code? And note that some code we write may be quite elegant but also rather mysterious and seeing it again a year later it may not be easy to see why we did that and whether some other way might not work as well. Decent comments explaining the algorithm and why choices were made may make all the difference. Or, they may make it easy to see how to convert the code to deal with one more or one less variable by changing it in the right places consistently. To answer something Chris said and was also mentioned here, I do not consider language design to be easy let alone implementing it. Not at all. BUT I think some changes can be straightforward. Having a symbol like a curly brace mean three new things may be tough to implement. Allowing a new symbol in an expanded set of characters seems more straightforward. Consider an arrow symbol → pointing to the right and another pointing the other way. Could we add the symbol to the language as a single character, albeit implemented using multiple bytes? If my editor let me insert the darn thing, it might then be a reasonable use for some construct in the language unique and new. Maybe the language would use the notation to hold objects holding a set and not confuse the notations for sets and dictionaries as Python ended up doing. (Yes, I know it is NOT confusing in some ways as one holds key:value pairs and the other just value, but making an empty set now requires the notation of set() while an empty dictionary is {} right? So how hard is it for a newly designed language to recognize any use of one arrow and expect everything up to the next arrow (pointing back) to be the contents of a set? It sounds a tad easier than now when Python interpreters have to pause when they see an open bracket and read what follows to see if everything beyond uses dictionary notation before it decides. But NO, I am not volunteering to do any of that. A language with too many symbols may be far worse. We cannot give every single object type their own symbols. But a few more than we have now might make it easier to create objects Python omitted and numpy and pandas and other modules had to add back the hard way. The only reason this is coming up is teh discussion of how various people react to the exact choice of how to add a new feature. I doubt people will like many choices in a new language created sort of like I describe, either. And nobody wants a new keyboard with a thousand keys, even if their language is Chinese. But there are days I want one a bit like that as I often write, as mentioned, in languages with additional characters or entirely other alphabets. Sigh. Life is complicated, then you die and it simplifies. -Original Message- From: Rob Cliffe via Python-list To: python-list@python.org Sent: Thu, Mar 3, 2022 8:41 pm Subject: Re: Behavior of the for-else constru
Re: Behavior of the for-else construct
I never feel confused by "else" because I always think it in "break...else", not "for...else". For those who always think in "for...else" deserves this confusion and it can't be just escaped by replacing with another magic word such as "then" or "finally" etc:-) --Jach -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 04/03/2022 00:55, Chris Angelico wrote: for victim in debtors: if victim.pay(up): continue if victim.late(): break or else: victim.sleep_with(fishes) If you mean "or else" to be synonymous with "else", then only the last debtor is killed, whether he has paid up or not, which seems a tad unfair (except that if there are no debtors either you will crash with a NameError or some random victim will be killed, which seems consistent with Mafia modus operandi while also being a trifle unfair. If (as I suspect) you mean "or else" to mean 'if a break occurred', then at least only one debtor is killed, as an example to the others, and no Exception will occur in the unlikely event of "debtors" being empty. Happy fund-raising! Rob Cliffe There's something in this. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 04/03/2022 01:44, Ethan Furman wrote: On 3/3/22 5:32 PM, Rob Cliffe via Python-list wrote: > There are three types of programmer: those that can count, and those that can't. Actually, there are 10 types of programmer: those that can count in binary, and those that can't. 1, 10, many. No problem. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 4/03/22 1:55 pm, Chris Angelico wrote: It's much better to treat arguments as a vector of strings rather than a single string, as the start command tries to. It would be nice if you could, but as I understand it, Windows always passes arguments to a program as a single string, and then it's up to the program to split it up how it wants. Different programs do that in different ways, hence the inconsistencies in how quoting and whitespace is handled. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 3/3/22 5:32 PM, Rob Cliffe via Python-list wrote: > There are three types of programmer: those that can count, and those that can't. Actually, there are 10 types of programmer: those that can count in binary, and those that can't. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 04/03/2022 00:43, Chris Angelico wrote: On Fri, 4 Mar 2022 at 11:14, Rob Cliffe via Python-list wrote: I find it so hard to remember what `for ... else` means that on the very few occasions I have used it, I ALWAYS put a comment alongside/below the `else` to remind myself (and anyone else unfortunate enough to read my code) what triggers it, e.g. for item in search_list: ... ... break else: # if no item in search_list matched the criteria A "break" statement always takes you to the line following the current loop construct. The "else" block is part of the current loop construct. It's no more a "no-break" block than the body of the for loop is a "no-break" body here: for item in stuff: if condition: break frobnicate(item) # if no previous item matched the condition You get the idea. If I really want to remember what this construct means, I remind myself that `else` here really means `no break`. Would have been better if it had been spelt `nobreak` or similar in the first place. Maybe, but I think that obscures the meaning of it; "finally" isn't quite right either (in a try block, you'd hit a finally block whether you raise an exception or not), but I think it's closer. Creating a new language keyword is an incredibly high cost. Think of it like this: for item in search_list: if condition: pass else: print("Condition not true for this item") for item in search_list: if condition: break else: print("Condition not true for any item") There's a parallel here. Since a for-else loop is basically useless without an if-break construct inside it, Yes but you have to remember what for-else means even to grasp that point. the else clause can be thought of as the else on a massive if/elif chain: if stuff[0].is_good: print("This item is good", stuff[0]) elif stuff[1].is_good: print("This item is good", stuff[1]) ... ... elif stuff[n].is_good: print("This item is good", stuff[n]) else: print("All items are bad") As a loop, this looks like this: for item in stuff: if item.is_good: print("This item is good", item) break else: print("All items are bad") The else is attached to the for so that it compasses ALL the if statements, but it's still broadly saying "do this when we don't hit the 'if' condition". Whether that's a sufficient mnemonic, I don't know, Not for me, I'm afraid. but it doesn't really matter; the construct is useful to those of us who want it, and if other people ignore it, that's fine. Nobody ever said you had to use or understand every single feature of the language you're using. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 04/03/2022 00:38, Avi Gross via Python-list wrote: Rob, I regularly code with lots of comments like the one you describe, or mark the end of a region that started on an earlier screen such as a deeply nested construct. So do I (and not just in Python). It's good practice. I have had problems though when I have shared such code and the recipient strips my comments and then later wants me to make changes or even just explain it! My reply tends to be unprintable as in, well, never mind! Quite justified. But why not make changes to/explain from *your* version, not his? This leads to a question I constantly ask. If you were free to design a brand new language now, what would you do different that existing languages have had to deal with the hard way? That's such a big question that I can't give an adequate answer. I recall when filenames and extensions had a limited number of characters allowed and embedded spaces were verboten. This regularity made lots of code possible but then some bright people insisted on allowing spaces and you can no longer easily do things like expand *.c into a long line of text and then unambiguously work on one file name at a time. You can often now create a name like "was file1.c and now is file2.c" and it seems acceptable. Yes, you can work around things and get a vector or list of strings and not a command line of text and all things considered, people can get as much or more work done. I have seen major struggles to get other character sets into languages. Any new language typically should have this built in from scratch and should consider adding non-ASCII characters into the mix. Mathematicians often use lots of weird braces/brackets as an example while normal programs are limited to [{( and maybe < and their counterparts. This leads to odd Python behavior (other languages too) where symbols are re-used ad nauseam. { can mean set or dictionary or simply some other way to group code. So I would love to see some key that allows you to do something like L* to mean the combination is a left bracket and should be treated as the beginning of a sequence expected to end in R* or perhaps *R. That would allow many other symbols to be viewed as balanced entities. Think of how Python expanded using single and double quotes (which arguably might work better if balanced this way) to sometimes using triple quotes to putting letters like "b" or "f" in front to make it a special kind of string. But I suspect programming might just get harder for those who would not appreciate a language that used (many) hundreds of symbols. +1. Just remembering how to type them all would be a burden. I do work in many alphabets and many of them pronounce and use letters that look familiar in very different ways and sound them differently and invent new ones. Every time I learn another human language, I have to both incorporate the new symbols and rules and also segregate them a bit from identical or similar things in the languages I already speak. It can be quite a chore. But still, I suspect many people are already familiar with symbols such as from set Theory such as subset and superset that could be used as another pair of parentheses of some type Having a way to enter them using keyboards is a challenge. Back to the topic, I was thinking wickedly of a way to extend the FOR loop with existing keywords while sounding a tad ominous is not with an ELSE but a FOR ... OR ELSE ... -Original Message- From: Rob Cliffe via Python-list To: python-list@python.org Sent: Thu, Mar 3, 2022 7:13 pm Subject: Re: Behavior of the for-else construct I find it so hard to remember what `for ... else` means that on the very few occasions I have used it, I ALWAYS put a comment alongside/below the `else` to remind myself (and anyone else unfortunate enough to read my code) what triggers it, e.g. for item in search_list: ... ... break else: # if no item in search_list matched the criteria You get the idea. If I really want to remember what this construct means, I remind myself that `else` here really means `no break`. Would have been better if it had been spelt `nobreak` or similar in the first place. Rob Cliffe On 03/03/2022 23:07, Avi Gross via Python-list wrote: The drumbeat I keep hearing is that some people hear/see the same word as implying something else. ELSE is ambiguous in the context it is used. And naturally, since nobody desperately wants to use non-reserved keywords, nobody seems ready to use a word like INSTEAD instead. Ideally, a language should be extendable and some languages like R allow you to place all kinds of things inside percent signs to make new operators like %*% or %PIPE% ... Just because some feature may be wanted is not a good reason to overly complicate a language. Can you imagine how hard it would be both to implement and read someth
Re: Behavior of the for-else construct
On 04/03/2022 00:34, Chris Angelico wrote: On Fri, 4 Mar 2022 at 10:09, Avi Gross via Python-list wrote: The drumbeat I keep hearing is that some people hear/see the same word as implying something else. ELSE is ambiguous in the context it is used. What I'm hearing is that there are, broadly speaking, two types of programmers [1]: 1) Those who think about "for-else" as a search tool and perfectly understand how it behaves 2) Those who have an incorrect idea about what for-else is supposed to do, don't understand it, and don't like it. Or those who have a vague fuzzy idea about it and have trouble remembering what it does. You could easily make a similar point about a lot of other advanced constructs. Some people don't understand threading, and either dislike it or are scared of it. Some people never get their heads around asyncio and the way that yield points work. Some people can't grok operator precedence, so they parenthesize everything "just to be safe". And some people dislike exceptions so much that they warp all their functions into returning a (value,True) or (error,False) tuple instead. Does this mean that all these features are bad? No. You could add examples ad nauseam. I submit that for-else is a special case. As evidenced by the number of people (including me) who say they have trouble grokking it. There's no way to make every feature perfectly intuitive to every programmer. Those features are still incredibly useful to the programmers that DO use them. Maybe, with hindsight, for-finally would have been a slightly better spelling than for-else. No. "finally" suggests (as analogy to try...finally) that the "finally" suit body is always executed. Presumably even if an untrapped exception occurs in the for-loop body (or even in the for-loop iterator). A for-loop can be terminated with "break" for many conceptually different reasons e.g. A search for a suitable item has found one. Something unexpected has happened. A pre-set allowed execution time has been exceeded. "nobreak"/"no_break" etc. is explicit and conceptually neutral. Who knows. But people simply need to understand it, just like people need to understand how binary floating-point works, and claiming that it's "ambiguous' is simply wrong. It has one meaning in the language, and then if programmers have an incorrect expectation, they need to learn (or to not use the feature, which isn't really a problem, it's just not taking advantage of it). And naturally, since nobody desperately wants to use non-reserved keywords, nobody seems ready to use a word like INSTEAD instead. Ideally, a language should be extendable and some languages like R allow you to place all kinds of things inside percent signs to make new operators like %*% or %PIPE% ... I don't know what you mean by "extendable", but if you mean that different people should be able to change the language syntax in different ways, then absolutely not. When two different files can be completely different languages based on a few directives, it's extremely difficult to read. +0.9, although I do sometimes wish for a macro feature in Python. Like, say, one that would translate "nobreak" into "else". (Import hooks, and tools like MacroPy, can be used for this sort of effect. I haven't tried MacroPy yet, maybe someday I will. I do not think that we should be using them on a regular basis to change core syntax.) Just because some feature may be wanted is not a good reason to overly complicate a language. Can you imagine how hard it would be both to implement and read something like: ... ELSE: ... OK: ... FINALLY: ... ULTIMATELY: ... What if multiple of things like the above example need to be triggered in some particular order? It would be easy to read if they were spelt sensibly, e.g. if_no_iterations: if_one_iteration: if_multiple_iterations: if_any_iterations: if_break: if_no_break: (I'm not saying that all of these are desirable, just conveying the idea.) If multiple clauses were triggered, they should be executed in the order in which they occur in the code. I don't know what they'd all mean, but if they were all in the core language, they would have to be supported in arbitrary combinations. It's possible to have a "try-except-else-finally" block in Python, for instance. But if you mean that they should all do what "else" does now, then this is a terrible idea. One way of spelling it is just fine. This reminds me a bit of how some programs add so much functionality because someone thought of it without wondering if anyone (including the ones who sponsored it) would ever want to use it or remember it is there or how. I recall how a version of emacs had a transpose-letter function so after typing "teh" you could hit control-t and a little mock LISP macro would go back and co a cut and go forward and do a paste and leave the cursor where it was. That was sometimes useful,
Re: Behavior of the for-else construct
Chris, Much of what I intended is similar to what you say. I am simply saying the existing group of programmers seems to include people who will not see every thing the same way. There is no way to make them all happy and you have other constraints like not suddenly adding new reserved words, so you do the best you can and hope people can get educated. I have seen lots of otherwise bright people drop out of math classes not because they could not understand the concepts, but because they have trouble handling all the symbols being used, such as Greek letters. Often they get stuck simply because nobody tells them how to pronounce the letter as in epsilon or zeta or aleph. Or consider the many ways various people denote a derivative. For some f'(x) and f''(x) feel right but dy/dx and d^2y/dx^2 (assume since this is plain next, I meant a small superscript 2 representing squared) makes no sense. Others like it the other way and still others like a dot on top of something like an s or two dots. I can mix and match many such representations because I know they are just representations of an underlying thing that I do understand. I have seen people then get stuck at partial derivatives which use a new symbol instead of the d, whose name they do not know like ∂ Teaching APL also drove some students crazy with all the overprinted symbols. So, yes, using ELSE in what seems to them like multiple and incompatible ways can lead to frustration but is rather unavoidable. Which leads to a point you misunderstood. I was saying R reserved a namespace of sorts so that adding new keywords could be done safely. Users are not expected to make variable names like %in% so you can write code like if (var %in% listing) and you can even change the definition in a sort of overloading to do something different. YES this can lead to others puzzling over your code. But if you need a new keyword, perhaps you could expand into such a reserved corner of the namespace and avoid having to reuse existing key words in possibly incompatible, or at least for some non-intuitive, ways. It does not need to use percent signs, just some notation users would normally not already be using. I am not here to say R is better, just some ideas are very different and thus many things chosen now are not inevitable. It gives me some flexibility in say calling a function as `[`(args) instead of [args] and rewriting it. Python plays lots of similar games, such as the decorators you like to use. In many places, Python makes it easier for me to do things. There really are more like three kinds of Programmers. Some see the world one way and some another way and some are switch hitters. The fourth kind tend not to be programmers! The ones who are adaptable and simply acknowledge that a decision has been made and use the functionality as it is done, do best. No need to complain, just adapt. And, of course, you can just not use anything that does not appeal to you but do not be shocked if you encounter code by others who are using it and be ready to understand it enough for the purpose at hand. If Python was being designed TODAY, I wonder if a larger set of key words would be marked as RESERVED for future expansion including ORELSE and even NEVERTHELESS. -Original Message- From: Chris Angelico To: python-list@python.org Sent: Thu, Mar 3, 2022 7:34 pm Subject: Re: Behavior of the for-else construct On Fri, 4 Mar 2022 at 10:09, Avi Gross via Python-list wrote: > > The drumbeat I keep hearing is that some people hear/see the same word as > implying something else. ELSE is ambiguous in the context it is used. > What I'm hearing is that there are, broadly speaking, two types of programmers [1]: 1) Those who think about "for-else" as a search tool and perfectly understand how it behaves 2) Those who have an incorrect idea about what for-else is supposed to do, don't understand it, and don't like it. You could easily make a similar point about a lot of other advanced constructs. Some people don't understand threading, and either dislike it or are scared of it. Some people never get their heads around asyncio and the way that yield points work. Some people can't grok operator precedence, so they parenthesize everything "just to be safe". And some people dislike exceptions so much that they warp all their functions into returning a (value,True) or (error,False) tuple instead. Does this mean that all these features are bad? No. There's no way to make every feature perfectly intuitive to every programmer. Those features are still incredibly useful to the programmers that DO use them. Maybe, with hindsight, for-finally would have been a slightly better spelling than for-else. Who knows. But people simply need to understand it, just like people need to understand how binary floating-point works, and claiming that it's "ambiguous' is simply wrong. It has one meaning in the l
Re: Behavior of the for-else construct
On Fri, 4 Mar 2022 at 11:39, Avi Gross via Python-list wrote: > > Rob, > > I regularly code with lots of comments like the one you describe, or mark the > end of a region that started on an earlier screen such as a deeply nested > construct. > > I have had problems though when I have shared such code and the recipient > strips my comments and then later wants me to make changes or even just > explain it! My reply tends to be unprintable as in, well, never mind! > If they strip out the comments, you can be confident that the comments were unhelpful :) > This leads to a question I constantly ask. If you were free to design a brand > new language now, what would you do different that existing languages have > had to deal with the hard way? > Very good way to start thinking. In fact, I'd recommend going further, and actually designing the entire language. (Don't bother actually writing an implementation, but fully lay out the syntax and semantics.) It's a great exercise, and you'll learn why things are the way they are. > I recall when filenames and extensions had a limited number of characters > allowed and embedded spaces were verboten. This regularity made lots of code > possible but then some bright people insisted on allowing spaces and you can > no longer easily do things like expand *.c into a long line of text and then > unambiguously work on one file name at a time. You can often now create a > name like "was file1.c and now is file2.c" and it seems acceptable. Yes, you > can work around things and get a vector or list of strings and not a command > line of text and all things considered, people can get as much or more work > done. > I don't remember when embedded spaces were verboten, so I'm guessing you're talking about 1970s or earlier, on mainframes? In MS-DOS, it was perfectly possible to have spaces in file names, and OS/2 also had that flexibility (and used it for special files like "EA DATA. SF" on a FAT disk). Windows forbade a bunch of characters in file names, but other systems have always been fine with them. It's not only file names that can be multiple words in a single logical argument. The Windows "start" command has a bizarreness where it takes a quoted string as a title, but a second quoted string as a file name, so <> will open that directory, <> opens a shell with a title of "c:\some_dir", and <> opens the directory, even if it has spaces in it. It's much better to treat arguments as a vector of strings rather than a single string, as the start command tries to. > I have seen major struggles to get other character sets into languages. Any > new language typically should have this built in from scratch and should > consider adding non-ASCII characters into the mix. Mathematicians often use > lots of weird braces/brackets as an example while normal programs are limited > to [{( and maybe < and their counterparts. This leads to odd Python behavior > (other languages too) where symbols are re-used ad nauseam. { can mean set or > dictionary or simply some other way to group code. > Tell me, which is more important: the way the code looks, or the way it is typed? Because your *editor* can control both of these. > So I would love to see some key that allows you to do something like L* to > mean the combination is a left bracket and should be treated as the beginning > of a sequence expected to end in R* or perhaps *R. That would allow many > other symbols to be viewed as balanced entities. Think of how Python expanded > using single and double quotes (which arguably might work better if balanced > this way) to sometimes using triple quotes to putting letters like "b" or "f" > in front to make it a special kind of string. > Okay. Design that in an editor and see if it catches on. I've seen a wide variety of bracket-matching tools (like color-coding all types of bracket according to what they pair with), but none of them really get popular. Baking it into the language means that everyone who uses the language has to be able to work with this. Flesh out this "L*" idea, and explain how it solves the problem. What does it do to the asterisk? > But I suspect programming might just get harder for those who would not > appreciate a language that used (many) hundreds of symbols. I do work in many > alphabets and many of them pronounce and use letters that look familiar in > very different ways and sound them differently and invent new ones. Every > time I learn another human language, I have to both incorporate the new > symbols and rules and also segregate them a bit from identical or similar > things in the languages I already speak. It can be quite a chore. But still, > I suspect many people are already familiar with symbols such as from set > Theory such as subset and superset that could be used as another pair of > parentheses of some type Having a way to enter them using keyboards is a > challenge. > Exactly. > Back to the topic, I was
Re: Behavior of the for-else construct
On Fri, 4 Mar 2022 at 11:14, Rob Cliffe via Python-list wrote: > > I find it so hard to remember what `for ... else` means that on the very > few occasions I have used it, I ALWAYS put a comment alongside/below the > `else` to remind myself (and anyone else unfortunate enough to read my > code) what triggers it, e.g. > > for item in search_list: > ... > ... break > else: # if no item in search_list matched the criteria A "break" statement always takes you to the line following the current loop construct. The "else" block is part of the current loop construct. It's no more a "no-break" block than the body of the for loop is a "no-break" body here: for item in stuff: if condition: break frobnicate(item) # if no previous item matched the condition > You get the idea. > If I really want to remember what this construct means, I remind myself > that `else` here really means `no break`. Would have been better if it > had been spelt `nobreak` or similar in the first place. Maybe, but I think that obscures the meaning of it; "finally" isn't quite right either (in a try block, you'd hit a finally block whether you raise an exception or not), but I think it's closer. Creating a new language keyword is an incredibly high cost. Think of it like this: for item in search_list: if condition: pass else: print("Condition not true for this item") for item in search_list: if condition: break else: print("Condition not true for any item") There's a parallel here. Since a for-else loop is basically useless without an if-break construct inside it, the else clause can be thought of as the else on a massive if/elif chain: if stuff[0].is_good: print("This item is good", stuff[0]) elif stuff[1].is_good: print("This item is good", stuff[1]) ... ... elif stuff[n].is_good: print("This item is good", stuff[n]) else: print("All items are bad") As a loop, this looks like this: for item in stuff: if item.is_good: print("This item is good", item) break else: print("All items are bad") The else is attached to the for so that it compasses ALL the if statements, but it's still broadly saying "do this when we don't hit the 'if' condition". Whether that's a sufficient mnemonic, I don't know, but it doesn't really matter; the construct is useful to those of us who want it, and if other people ignore it, that's fine. Nobody ever said you had to use or understand every single feature of the language you're using. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
Rob, I regularly code with lots of comments like the one you describe, or mark the end of a region that started on an earlier screen such as a deeply nested construct. I have had problems though when I have shared such code and the recipient strips my comments and then later wants me to make changes or even just explain it! My reply tends to be unprintable as in, well, never mind! This leads to a question I constantly ask. If you were free to design a brand new language now, what would you do different that existing languages have had to deal with the hard way? I recall when filenames and extensions had a limited number of characters allowed and embedded spaces were verboten. This regularity made lots of code possible but then some bright people insisted on allowing spaces and you can no longer easily do things like expand *.c into a long line of text and then unambiguously work on one file name at a time. You can often now create a name like "was file1.c and now is file2.c" and it seems acceptable. Yes, you can work around things and get a vector or list of strings and not a command line of text and all things considered, people can get as much or more work done. I have seen major struggles to get other character sets into languages. Any new language typically should have this built in from scratch and should consider adding non-ASCII characters into the mix. Mathematicians often use lots of weird braces/brackets as an example while normal programs are limited to [{( and maybe < and their counterparts. This leads to odd Python behavior (other languages too) where symbols are re-used ad nauseam. { can mean set or dictionary or simply some other way to group code. So I would love to see some key that allows you to do something like L* to mean the combination is a left bracket and should be treated as the beginning of a sequence expected to end in R* or perhaps *R. That would allow many other symbols to be viewed as balanced entities. Think of how Python expanded using single and double quotes (which arguably might work better if balanced this way) to sometimes using triple quotes to putting letters like "b" or "f" in front to make it a special kind of string. But I suspect programming might just get harder for those who would not appreciate a language that used (many) hundreds of symbols. I do work in many alphabets and many of them pronounce and use letters that look familiar in very different ways and sound them differently and invent new ones. Every time I learn another human language, I have to both incorporate the new symbols and rules and also segregate them a bit from identical or similar things in the languages I already speak. It can be quite a chore. But still, I suspect many people are already familiar with symbols such as from set Theory such as subset and superset that could be used as another pair of parentheses of some type Having a way to enter them using keyboards is a challenge. Back to the topic, I was thinking wickedly of a way to extend the FOR loop with existing keywords while sounding a tad ominous is not with an ELSE but a FOR ... OR ELSE ... -Original Message- From: Rob Cliffe via Python-list To: python-list@python.org Sent: Thu, Mar 3, 2022 7:13 pm Subject: Re: Behavior of the for-else construct I find it so hard to remember what `for ... else` means that on the very few occasions I have used it, I ALWAYS put a comment alongside/below the `else` to remind myself (and anyone else unfortunate enough to read my code) what triggers it, e.g. for item in search_list: ... ... break else: # if no item in search_list matched the criteria You get the idea. If I really want to remember what this construct means, I remind myself that `else` here really means `no break`. Would have been better if it had been spelt `nobreak` or similar in the first place. Rob Cliffe On 03/03/2022 23:07, Avi Gross via Python-list wrote: > The drumbeat I keep hearing is that some people hear/see the same word as > implying something else. ELSE is ambiguous in the context it is used. > > And naturally, since nobody desperately wants to use non-reserved keywords, > nobody seems ready to use a word like INSTEAD instead. > > Ideally, a language should be extendable and some languages like R allow you > to place all kinds of things inside percent signs to make new operators like > %*% or %PIPE% ... > > Just because some feature may be wanted is not a good reason to overly > complicate a language. Can you imagine how hard it would be both to implement > and read something like: > > ... > ELSE: > ... > OK: > ... > FINALLY: > ... > ULTIMATELY: > ... > > What if multiple of things like the above example need to be triggered in > some particular order? > > I have to wonder if some new
Re: Behavior of the for-else construct
On Fri, 4 Mar 2022 at 10:09, Avi Gross via Python-list wrote: > > The drumbeat I keep hearing is that some people hear/see the same word as > implying something else. ELSE is ambiguous in the context it is used. > What I'm hearing is that there are, broadly speaking, two types of programmers [1]: 1) Those who think about "for-else" as a search tool and perfectly understand how it behaves 2) Those who have an incorrect idea about what for-else is supposed to do, don't understand it, and don't like it. You could easily make a similar point about a lot of other advanced constructs. Some people don't understand threading, and either dislike it or are scared of it. Some people never get their heads around asyncio and the way that yield points work. Some people can't grok operator precedence, so they parenthesize everything "just to be safe". And some people dislike exceptions so much that they warp all their functions into returning a (value,True) or (error,False) tuple instead. Does this mean that all these features are bad? No. There's no way to make every feature perfectly intuitive to every programmer. Those features are still incredibly useful to the programmers that DO use them. Maybe, with hindsight, for-finally would have been a slightly better spelling than for-else. Who knows. But people simply need to understand it, just like people need to understand how binary floating-point works, and claiming that it's "ambiguous' is simply wrong. It has one meaning in the language, and then if programmers have an incorrect expectation, they need to learn (or to not use the feature, which isn't really a problem, it's just not taking advantage of it). > And naturally, since nobody desperately wants to use non-reserved keywords, > nobody seems ready to use a word like INSTEAD instead. > > Ideally, a language should be extendable and some languages like R allow you > to place all kinds of things inside percent signs to make new operators like > %*% or %PIPE% ... > I don't know what you mean by "extendable", but if you mean that different people should be able to change the language syntax in different ways, then absolutely not. When two different files can be completely different languages based on a few directives, it's extremely difficult to read. (Import hooks, and tools like MacroPy, can be used for this sort of effect. I do not think that we should be using them on a regular basis to change core syntax.) > Just because some feature may be wanted is not a good reason to overly > complicate a language. Can you imagine how hard it would be both to implement > and read something like: > > ... > ELSE: >... > OK: >... > FINALLY: >... > ULTIMATELY: >... > > What if multiple of things like the above example need to be triggered in > some particular order? I don't know what they'd all mean, but if they were all in the core language, they would have to be supported in arbitrary combinations. It's possible to have a "try-except-else-finally" block in Python, for instance. But if you mean that they should all do what "else" does now, then this is a terrible idea. One way of spelling it is just fine. > This reminds me a bit of how some programs add so much functionality because > someone thought of it without wondering if anyone (including the ones who > sponsored it) would ever want to use it or remember it is there or how. I > recall how a version of emacs had a transpose-letter function so after typing > "teh" you could hit control-t and a little mock LISP macro would go back and > co a cut and go forward and do a paste and leave the cursor where it was. > That was sometimes useful, but often just as easy to backspace and retype. > But I recall gleefully adding a transpose for words, sentences, paragraphs > and was going to add more but I was running out of keystrokes to bind them to > and besides it can be fairly easy to select items and yank them and move to > where you want them and replace them. > SciTE has a "transpose lines" feature. I use it frequently. But editor features are quite different from language features. ChrisA [1] Something tells me I've heard this before -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
I find it so hard to remember what `for ... else` means that on the very few occasions I have used it, I ALWAYS put a comment alongside/below the `else` to remind myself (and anyone else unfortunate enough to read my code) what triggers it, e.g. for item in search_list: ... ... break else: # if no item in search_list matched the criteria You get the idea. If I really want to remember what this construct means, I remind myself that `else` here really means `no break`. Would have been better if it had been spelt `nobreak` or similar in the first place. Rob Cliffe On 03/03/2022 23:07, Avi Gross via Python-list wrote: The drumbeat I keep hearing is that some people hear/see the same word as implying something else. ELSE is ambiguous in the context it is used. And naturally, since nobody desperately wants to use non-reserved keywords, nobody seems ready to use a word like INSTEAD instead. Ideally, a language should be extendable and some languages like R allow you to place all kinds of things inside percent signs to make new operators like %*% or %PIPE% ... Just because some feature may be wanted is not a good reason to overly complicate a language. Can you imagine how hard it would be both to implement and read something like: ... ELSE: ... OK: ... FINALLY: ... ULTIMATELY: ... What if multiple of things like the above example need to be triggered in some particular order? I have to wonder if some new form of wrapper might have made as much sense as in you wrap your loop in something that sets up and traps various signals that are then produced under conditions specified such as the loop not being entered as the starting condition is sort of null, or an exit due to a break or simply because the code itself throws that signal to be caught ... This reminds me a bit of how some programs add so much functionality because someone thought of it without wondering if anyone (including the ones who sponsored it) would ever want to use it or remember it is there or how. I recall how a version of emacs had a transpose-letter function so after typing "teh" you could hit control-t and a little mock LISP macro would go back and co a cut and go forward and do a paste and leave the cursor where it was. That was sometimes useful, but often just as easy to backspace and retype. But I recall gleefully adding a transpose for words, sentences, paragraphs and was going to add more but I was running out of keystrokes to bind them to and besides it can be fairly easy to select items and yank them and move to where you want them and replace them. To make changes in a language is sometimes really expensive but also dangerous. A "free" language must be added to sparingly and with so many requests, perhaps only a few non bug-fixes can seriously be considered. -Original Message- From: Akkana Peck To: python-list@python.org Sent: Thu, Mar 3, 2022 5:33 pm Subject: Re: Behavior of the for-else construct computermaster360 writes: I want to make a little survey here. Do you find the for-else construct useful? No. Have you used it in practice? Once or twice, but ended up removing it, see below. Do you even know how it works, or that there is such a thing in Python? I always have to look it up, because to my mind, "else" implies it does something quite different from what it actually does. Which means that even if I worked hard at memorizing what it does, so I didn't have to look it up, I still wouldn't use it in code, because I want my code to be easily readable (including by future-me). for..else makes code difficult to understand by anyone who doesn't use for..else frequently: they might be misled into misunderstanding the control flow. ...Akkana -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
The drumbeat I keep hearing is that some people hear/see the same word as implying something else. ELSE is ambiguous in the context it is used. And naturally, since nobody desperately wants to use non-reserved keywords, nobody seems ready to use a word like INSTEAD instead. Ideally, a language should be extendable and some languages like R allow you to place all kinds of things inside percent signs to make new operators like %*% or %PIPE% ... Just because some feature may be wanted is not a good reason to overly complicate a language. Can you imagine how hard it would be both to implement and read something like: ... ELSE: ... OK: ... FINALLY: ... ULTIMATELY: ... What if multiple of things like the above example need to be triggered in some particular order? I have to wonder if some new form of wrapper might have made as much sense as in you wrap your loop in something that sets up and traps various signals that are then produced under conditions specified such as the loop not being entered as the starting condition is sort of null, or an exit due to a break or simply because the code itself throws that signal to be caught ... This reminds me a bit of how some programs add so much functionality because someone thought of it without wondering if anyone (including the ones who sponsored it) would ever want to use it or remember it is there or how. I recall how a version of emacs had a transpose-letter function so after typing "teh" you could hit control-t and a little mock LISP macro would go back and co a cut and go forward and do a paste and leave the cursor where it was. That was sometimes useful, but often just as easy to backspace and retype. But I recall gleefully adding a transpose for words, sentences, paragraphs and was going to add more but I was running out of keystrokes to bind them to and besides it can be fairly easy to select items and yank them and move to where you want them and replace them. To make changes in a language is sometimes really expensive but also dangerous. A "free" language must be added to sparingly and with so many requests, perhaps only a few non bug-fixes can seriously be considered. -Original Message- From: Akkana Peck To: python-list@python.org Sent: Thu, Mar 3, 2022 5:33 pm Subject: Re: Behavior of the for-else construct computermaster360 writes: > I want to make a little survey here. > > Do you find the for-else construct useful? No. > Have you used it in practice? Once or twice, but ended up removing it, see below. > Do you even know how it works, or that there is such a thing in Python? I always have to look it up, because to my mind, "else" implies it does something quite different from what it actually does. Which means that even if I worked hard at memorizing what it does, so I didn't have to look it up, I still wouldn't use it in code, because I want my code to be easily readable (including by future-me). for..else makes code difficult to understand by anyone who doesn't use for..else frequently: they might be misled into misunderstanding the control flow. ...Akkana -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
computermaster360 writes: > I want to make a little survey here. > > Do you find the for-else construct useful? No. > Have you used it in practice? Once or twice, but ended up removing it, see below. > Do you even know how it works, or that there is such a thing in Python? I always have to look it up, because to my mind, "else" implies it does something quite different from what it actually does. Which means that even if I worked hard at memorizing what it does, so I didn't have to look it up, I still wouldn't use it in code, because I want my code to be easily readable (including by future-me). for..else makes code difficult to understand by anyone who doesn't use for..else frequently: they might be misled into misunderstanding the control flow. ...Akkana -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-03, computermaster360 wrote: > Do you find the for-else construct useful? Have you used it in > practice? Yes, I use it frequently. > I have used it maybe once. My issue with this construct is that > calling the second block `else` doesn't make sense; a much more > sensible name would be `then`. You are not the only person with this opinion, although personally I have the opposite opinion. I think of 'for...else' as being a search for something that matches a condition, and the 'else' block is if no item is found that matches. If you think of it like that, the syntax makes perfect sense. > Now, imagine a parallel universe, where the for-else construct would > have a different behavior: > > for elem in iterable: > process(elem) > else: > # executed only when the iterable was initially empty > print('Nothing to process') > > Wouldn't this be more natural? I think so. Also, I face this case much > more often than having detect whether I broke out of a loop early > (which is what the current for-else construct is for). I guess peoples' needs vary. I can't even remember the last time I've needed something as you suggest above - certainly far less often than I need 'for...else' as it is now. > What are your thoughts? Do you agree? I don't agree. But it doesn't really matter if anyone agrees or not, since there is no chance whatsoever that a valid Python syntax is suddenly going to change to mean something completely different, not even in "Python 4000" or whatever far-future version we might imagine. This exact topic was discussd in November 2017 by the way, under the subject heading "Re: replacing `else` with `then` in `for` and `try`". I'm not sure any particular conclusion was reached though except that some people think 'else' is more intuitive and some people think 'then' would be more intuitive. -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 03/03/2022 07.24, computermaster360 wrote: I want to make a little survey here. Do you find the for-else construct useful? Have you used it in practice? Do you even know how it works, or that there is such a thing in Python? I only found out about it within the last year or so. I've used it probably half-a-dozen times. It seems quite elegant to me. -- Michael F. Stemper A preposition is something you should never end a sentence with. -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Thu, 3 Mar 2022 at 18:25, Schachner, Joseph wrote: > I don't know what that would be. "finally" is available Write up a > feature request. Not sure if you mean `finally` seriously but I think that would about as confusing as the current `else`, if not even more Meanwhile, I found another solution which is somewhat neater than using a boolean flag: item = sentinel = object() for item in iterable: do_stuff(item) if item is sentinel: print('No items in iterable!') -- https://mail.python.org/mailman/listinfo/python-list
RE: Behavior of the for-else construct
Useful: On rare occasions (when a loop has a "break" in it) Used: Yes Know how it works: Yes Even is such a thing: Yes Your suggestion: Also useful. Will require a different keyword. I don't know what that would be. "finally" is available Write up a feature request. --- Joseph S. Teledyne Confidential; Commercially Sensitive Business Data -Original Message- From: computermaster360 Sent: Thursday, March 3, 2022 8:24 AM To: python-list@python.org Subject: Behavior of the for-else construct I want to make a little survey here. Do you find the for-else construct useful? Have you used it in practice? Do you even know how it works, or that there is such a thing in Python? I have used it maybe once. My issue with this construct is that calling the second block `else` doesn't make sense; a much more sensible name would be `then`. Now, imagine a parallel universe, where the for-else construct would have a different behavior: for elem in iterable: process(elem) else: # executed only when the iterable was initially empty print('Nothing to process') Wouldn't this be more natural? I think so. Also, I face this case much more often than having detect whether I broke out of a loop early (which is what the current for-else construct is for). Now someone may argue that it's easy to check whether the iterable is empty beforehand. But is it really? What if it's an iterator? Then one would have to resort to using a flag variable and set it in each iteration of the loop. An ugly alternative would be trying to retrieve the first element of the iterable separately, in a try block before the for-loop, to find out whether the iterable is empty. This would of course require making an iterator of the iterable first (since we can't be sure it is already an iterator), and then -- if there are any elements -- processing the first element separately before the for-loop, which means duplicating the loop body. You can see the whole thing gets really ugly really quickly... What are your thoughts? Do you agree? Or am I just not Dutch enough...? -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
computermaster360 wrote at 2022-3-3 14:24 +0100: >Do you find the for-else construct useful? Yes. >Have you used it in practice? Yes -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
It has occasional uses (I THINK I've used it myself) but spelling it `else` is very confusing. So there have been proposals for an alternative spelling, e.g. `nobreak`. There have also been suggestions for adding other suites after `for', e.g. if the loop WAS exited with `break` if the loop was executed zero times but these have not been accepted. Best wishes Rob Cliffe On 03/03/2022 13:24, computermaster360 wrote: I want to make a little survey here. Do you find the for-else construct useful? Have you used it in practice? Do you even know how it works, or that there is such a thing in Python? I have used it maybe once. My issue with this construct is that calling the second block `else` doesn't make sense; a much more sensible name would be `then`. Now, imagine a parallel universe, where the for-else construct would have a different behavior: for elem in iterable: process(elem) else: # executed only when the iterable was initially empty print('Nothing to process') Wouldn't this be more natural? I think so. Also, I face this case much more often than having detect whether I broke out of a loop early (which is what the current for-else construct is for). Now someone may argue that it's easy to check whether the iterable is empty beforehand. But is it really? What if it's an iterator? Then one would have to resort to using a flag variable and set it in each iteration of the loop. An ugly alternative would be trying to retrieve the first element of the iterable separately, in a try block before the for-loop, to find out whether the iterable is empty. This would of course require making an iterator of the iterable first (since we can't be sure it is already an iterator), and then -- if there are any elements -- processing the first element separately before the for-loop, which means duplicating the loop body. You can see the whole thing gets really ugly really quickly... What are your thoughts? Do you agree? Or am I just not Dutch enough...? -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
Op 3/03/2022 om 14:24 schreef computermaster360: I want to make a little survey here. Do you find the for-else construct useful? Have you used it in practice? Do you even know how it works, or that there is such a thing in Python? - No, or at least not when balanced against the drawbacks as I perceive them. - I have a hard time remembering how it works, which is the major drawback for me. I simply can't seem to wrap my head around it. - Yes I have used it maybe once. My issue with this construct is that calling the second block `else` doesn't make sense; a much more sensible name would be `then`. There have been multiple proposals for a better name, but they all have their own drawbacks. There doesn't seem to be a clear winner. Maybe a bit of an explanation of my dislike for the for-else construct. I can't remember what exactly it does and doesn't do, maybe because of the IMHO unfortunate naming or maybe because it's just an unusal construct, I don't know. While coding I never feel the need for for-else. I like coding in a way where "every line expresses a single thought", as much as possible. That means that I don't mine creating short functions for things that in my mind otherwise break the flow of my code. So I often have short functions with a for loop and early returns. I have never seen an example of for-else that wouldn't be at least as clear with a little helper function (granted I haven't looked all that hard). I'm googling for an example, but all I find are tutorial-type things that don't necessarily compare to real code. But it's the best I can do, so let's dive in. What they all seem to have in common is that they mix business logic and user interface (maybe precisely because of their tutorial nature), which I strive to avoid. For example, on https://www.geeksforgeeks.org/using-else-conditional-statement-with-for-loop-in-python/ I found this example: # Python 3.x program to check if an array consists # of even number def contains_even_number(l): for ele in l: if ele % 2 == 0: print ("list contains an even number") break # This else executes only if break is NEVER # reached and loop terminated after all iterations. else: print ("list does not contain an even number") # Driver code print ("For List 1:") contains_even_number([1, 9, 8]) print (" \nFor List 2:") contains_even_number([1, 3, 5]) I would always refactor this even just for that mixing of business logic and printing stuff. Perhaps like this: def contains_even_number(lst): for element in lst: if element % 2 == 0: return True return False def print_contains_even_number(lst): if contains_even_number(lst): print("list contains an even number") else: print("list does not contain an even number") print("For List 1:") print_contains_even_number([1, 9, 8]) print() print("For List 2:") print_contains_even_number([1, 3, 5]) Even without consciously avoiding for-else, it automatically disappears. (In real code I would actually use any(element % 2 == 0 for element in lst) for something simple like this) Now, imagine a parallel universe, where the for-else construct would have a different behavior: for elem in iterable: process(elem) else: # executed only when the iterable was initially empty print('Nothing to process') Wouldn't this be more natural? I think so. Also, I face this case much more often than having detect whether I broke out of a loop early (which is what the current for-else construct is for). That's a different construct, also possibly useful. I think this would be more useful to me than the existing for-else. -- "Man had always assumed that he was more intelligent than dolphins because he had achieved so much — the wheel, New York, wars and so on — whilst all the dolphins had ever done was muck about in the water having a good time. But conversely, the dolphins had always believed that they were far more intelligent than man — for precisely the same reasons." -- Douglas Adams -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-03, computermaster360 wrote: > Do you find the for-else construct useful? Yes. > Have you used it in practice? Yes. I don't use it often, but I do use it occasionally. However, I always have to look it up the docs to confirm the logic. I always feel like the else should be executed if the for loop does _not_ terminate naturally, but it's the opposite. > Now, imagine a parallel universe, where the for-else construct would > have a different behavior: > > for elem in iterable: > process(elem) > else: > # executed only when the iterable was initially empty > print('Nothing to process') > > Wouldn't this be more natural? That also make sense. > I think so. Also, I face this case much more often than having > detect whether I broke out of a loop early (which is what the > current for-else construct is for). -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On 2022-03-04 02:02, Chris Angelico wrote: >> I want to make a little survey here. >> >> Do you find the for-else construct useful? Have you used it in >> practice? Do you even know how it works, or that there is such a >> thing in Python? > > Yes, yes, and yes-yes. It's extremely useful. Just adding another data-point, my answer is the same as above. I use it regularly and frequently wish for it (or a similar "didn't trigger a break-condition in the loop" functionality) when using other programming languages. -tkc -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
> On 3 Mar 2022, at 13:24, computermaster360 > wrote: > > I want to make a little survey here. > > Do you find the for-else construct useful? No. I always have to look up what condition the else fires on. > Have you used it in > practice? No. > Do you even know how it works, or that there is such a thing > in Python? Yes (when I read the docs) and yes. > I have used it maybe once. My issue with this construct is that > calling the second block `else` doesn't make sense; a much more > sensible name would be `then`. There was a thread on this list asking for alternative syntax for the for: else: that was not taken up. Something like nobreak: instead of else: > > Now, imagine a parallel universe, where the for-else construct would > have a different behavior: > >for elem in iterable: >process(elem) >else: ># executed only when the iterable was initially empty >print('Nothing to process') > > Wouldn't this be more natural? I think so. Also, I face this case much > more often than having detect whether I broke out of a loop early > (which is what the current for-else construct is for). > > Now someone may argue that it's easy to check whether the iterable is > empty beforehand. But is it really? What if it's an iterator? > Then one would have to resort to using a flag variable and set it in > each iteration of the loop. An ugly alternative would be trying to > retrieve > the first element of the iterable separately, in a try block before > the for-loop, to find out whether the iterable is empty. This would of > course > require making an iterator of the iterable first (since we can't be > sure it is already an iterator), and then -- if there are any elements > -- processing > the first element separately before the for-loop, which means > duplicating the loop body. You can see the whole thing gets really > ugly really quickly... > > What are your thoughts? Do you agree? Or am I just not Dutch enough...? Barry > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Fri, 4 Mar 2022 at 00:25, computermaster360 wrote: > > I want to make a little survey here. > > Do you find the for-else construct useful? Have you used it in > practice? Do you even know how it works, or that there is such a thing > in Python? Yes, yes, and yes-yes. It's extremely useful. > I have used it maybe once. My issue with this construct is that > calling the second block `else` doesn't make sense; a much more > sensible name would be `then`. Ehh, I think "finally" would be a better keyword, but that has very close connections with exception handling. > Now, imagine a parallel universe, where the for-else construct would > have a different behavior: > > for elem in iterable: > process(elem) > else: > # executed only when the iterable was initially empty > print('Nothing to process') > > Wouldn't this be more natural? I think so. Also, I face this case much > more often than having detect whether I broke out of a loop early > (which is what the current for-else construct is for). This also has value, but not as much. > Now someone may argue that it's easy to check whether the iterable is > empty beforehand. But is it really? What if it's an iterator? > Then one would have to resort to using a flag variable and set it in > each iteration of the loop. An ugly alternative would be trying to > retrieve > the first element of the iterable separately, in a try block before > the for-loop, to find out whether the iterable is empty. This would of > course > require making an iterator of the iterable first (since we can't be > sure it is already an iterator), and then -- if there are any elements > -- processing > the first element separately before the for-loop, which means > duplicating the loop body. You can see the whole thing gets really > ugly really quickly... > > What are your thoughts? Do you agree? Or am I just not Dutch enough...? Both forms have value, and only one of them can be called for-else. Maybe if the current one had been called for-finally, then what you're proposing could have been for-else, and we could theoretically have had for-else-finally (where it goes into the for block once for each element, but if there aren't any, it goes into the else block instead, and either way, if you never break, it goes into the finally before moving on). That ship has sailed, though, and given that people would be confused very greatly by for-finally, I'm not overly sorry with the current state of affairs. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Behavior of the for-else construct
On Thu, Mar 3, 2022 at 5:24 AM computermaster360 < computermaster...@gmail.com> wrote: > I want to make a little survey here. > > Do you find the for-else construct useful? Have you used it in > practice? Do you even know how it works, or that there is such a thing > in Python? > > I have used it maybe once. My issue with this construct is that > calling the second block `else` doesn't make sense; a much more > sensible name would be `then`. > I use it and like it. You need break's to make it useful - then it cuts down on unnecessary booleans. -- https://mail.python.org/mailman/listinfo/python-list
Behavior of the for-else construct
I want to make a little survey here. Do you find the for-else construct useful? Have you used it in practice? Do you even know how it works, or that there is such a thing in Python? I have used it maybe once. My issue with this construct is that calling the second block `else` doesn't make sense; a much more sensible name would be `then`. Now, imagine a parallel universe, where the for-else construct would have a different behavior: for elem in iterable: process(elem) else: # executed only when the iterable was initially empty print('Nothing to process') Wouldn't this be more natural? I think so. Also, I face this case much more often than having detect whether I broke out of a loop early (which is what the current for-else construct is for). Now someone may argue that it's easy to check whether the iterable is empty beforehand. But is it really? What if it's an iterator? Then one would have to resort to using a flag variable and set it in each iteration of the loop. An ugly alternative would be trying to retrieve the first element of the iterable separately, in a try block before the for-loop, to find out whether the iterable is empty. This would of course require making an iterator of the iterable first (since we can't be sure it is already an iterator), and then -- if there are any elements -- processing the first element separately before the for-loop, which means duplicating the loop body. You can see the whole thing gets really ugly really quickly... What are your thoughts? Do you agree? Or am I just not Dutch enough...? -- https://mail.python.org/mailman/listinfo/python-list