Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
On Sun, Mar 4, 2018 at 11:04 PM, Chris Angelico wrote: > On Mon, Mar 5, 2018 at 2:49 PM, Mike Miller > wrote: > > Yes, thanks: > > > > [ f(y), g(y) for x, h(x) as y in things ] > > > > > > Dyslexics untie! > > :) > > Hmm. The trouble here is that a 'for' loop is basically doing > assignment. When you say "for x, h(x) as y in things", what Python > does is (simplified): > > _it = iter(things) > while not StopIteration: > x, (h(x) as y) = next(_it) > ... loop body ... > > So what you're asking for is something that doesn't behave like an > assignment target, but just does its own assignment. Bear in mind, > too, that "x = next(_it)" is very different from "x, = next(_it)"; > which one is "x, (h(x) as y) = next(_it)" more like? > > If I understood Mike's proposal correctly it was to allow "," to mean 'given' in this context when followed by EXPRESSION "as" VARIABLE, rather than its usual iterable-unpacking meaning. But I think this would cause confusion. Suppose `things` contains pair-tuples. Then you could have [ f(y), g(y) for x1, x2, h(x1) as y in things ] which makes it look like (x1, x2, h(x1)) go together rather than just (x1, x2). Nathan ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
On Mon, Mar 5, 2018 at 2:49 PM, Mike Miller wrote: > Yes, thanks: > > [ f(y), g(y) for x, h(x) as y in things ] > > > Dyslexics untie! :) Hmm. The trouble here is that a 'for' loop is basically doing assignment. When you say "for x, h(x) as y in things", what Python does is (simplified): _it = iter(things) while not StopIteration: x, (h(x) as y) = next(_it) ... loop body ... So what you're asking for is something that doesn't behave like an assignment target, but just does its own assignment. Bear in mind, too, that "x = next(_it)" is very different from "x, = next(_it)"; which one is "x, (h(x) as y) = next(_it)" more like? ChrisA ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
Yes, thanks: [ f(y), g(y) for x, h(x) as y in things ] Dyslexics untie! On 2018-03-04 19:45, Chris Angelico wrote: ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
On Mon, Mar 5, 2018 at 2:39 PM, Mike Miller wrote: > > On 2018-03-03 16:51, Greg Ewing wrote: >>> >>> 2018-03-03 8:40 GMT+01:00 Nick Coghlan : pairs = [(f(y), g(y)) for x in things with bind(h(x)) as y] >> >> >> I don't mucn like "with bind(h(x)) as y" because it's kind of >> like an abstraction inversion -- you're building something >> complicated on top of something complicated in order to get >> something simple, instead of just having the simple thing >> to begin with. If nothing else, it has a huge runtime cost >> for the benefit it gives. > > > Reading this thread I was thinking that the assignment part was happening > too far away from where the action was and came up with this variant: > > [ f(y), g(y) for x, y as h(x) in things ] > > Plus or minus an extra set of parentheses for clarity. Did you mean: [ f(y), g(y) for x, h(x) as y in things ] ? Elsewhere in Python, "a as b" takes "a" and binds it to the name "b". Otherwise, I'm not sure what you meant. ChrisA ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
On 2018-03-03 16:51, Greg Ewing wrote: 2018-03-03 8:40 GMT+01:00 Nick Coghlan : pairs = [(f(y), g(y)) for x in things with bind(h(x)) as y] I don't mucn like "with bind(h(x)) as y" because it's kind of like an abstraction inversion -- you're building something complicated on top of something complicated in order to get something simple, instead of just having the simple thing to begin with. If nothing else, it has a huge runtime cost for the benefit it gives. Reading this thread I was thinking that the assignment part was happening too far away from where the action was and came up with this variant: [ f(y), g(y) for x, y as h(x) in things ] Plus or minus an extra set of parentheses for clarity. -Mike ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
> I know Guido is on record as not wanting to allow both "for name in > sequence" and "for name = expr" due to that being a very subtle distinction > between iteration and simple assignment (especially given that Julia uses > them as alternate spellings for the same thing), but I'm wondering if it may > be worth considering such a distinction in *with statements*, such that we > allowed "with name = expr" in addition to "with cm as name" (where "name = > expr" is just an ordinary assignment statement that doesn't trigger the > context management protocol). > > The related enhancement to comprehensions would then be to allow with > clauses to be interleaved between the for loops and the if statements, such > that you could write things like: > > pairs = [(f(y), g(y)) for x in things with y = h(x)] > contents = [f.read() for fname in filenames with open(fname) as f] > > while still preserving the property where comprehensions can be correctly > interpreted just by converting each of the clauses to the corresponding > statement form. > > Even without the "with name = expr" change, allowing with clauses in > comprehensions would let you do (by way of a suitably defined "bind" CM): > > pairs = [(f(y), g(y)) for x in things with bind(h(x)) as y] Including standard "with open(...) as f" context management in list comprehensions would also be a good idea, I think it's in the same idea as including : allowing both statements (imperative programming) and list comprehension (more "functional"). The same story goes for exceptions : for x in range(5): try: yield f(x) except Exception: yield 0 isn't "refactorable" as a list comprehension like : [try f(i) except Exception: 0 for x in range(5)] But I think that would cover another subject :) But if the "with =" syntax is accepted for simple assignment, it could indeed introduce a confusion compared to the "with as" in context management, and having a complete different keyword (or punctuation) is maybe be better. As a symmetry, we could also introduce the "with =" syntax in normal statement :P that'd do a normal assignement, although that's be probably stupid because normal assignements works well. Robert ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
> What the heck, if it was good enough for PL/1... It would still be parsable indeed. A keyword available in a context would then be something new in the language. > Choice of syntax is important, though. It's all very well > to come up with an "insert syntax here" proposal that has > some big obvious benefit, but if you can't actually come > up with a pleasing syntax for it, then it won't fly. So > it makes sense to consider potential syntaxes along with > other aspects of a proposal. Of course the syntax is very important, that's why we make a list of pro's and con's about each syntax. However, people also want to know if the feature is useful for a lot of users. So, should we do that list somewhere ? :) ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
> Robert Vanden Eynde wrote: >> >> But I think that the implementation of print(y with y = x + 1) would >> be more close to next(y for y in [ x+1 ]) > > > WHy on earth should it be? Expanding that gives you a generator > containing a loop that only executes once that is immediately run > to yield exactly one value. Why bother with all that overhead? > You're probably right. ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
Nick Coghlan writes: > pairs = [(f(y), g(y)) for x in things with y = h(x)] > contents = [f.read() for fname in filenames with open(fname) as f] This is horrible. I think Julia is just weird: in normal English we do distinguish between equality and membership. "x in y" is a very different statement from "x = y". I think even Guido would come around to the view if it were implemented (assuming not "over his dead body"). But the semantics of "x = y" and "y as x" in English are both pretty much the copula. It's hard enough to stay aware that there be dragons in a context manager; if "with" could denote a simple (local) binding, it would require conscious effort. > Even without the "with name = expr" change, allowing with clauses in > comprehensions would let you do (by way of a suitably defined "bind" CM): > > pairs = [(f(y), g(y)) for x in things with bind(h(x)) as y] This is *much* better. But suppose you wanted to have *several* bindings. Would this syntax allow "destructuring" of tuples (as the for clause will do): pairs = [(f(x) + g(y), f(x) - g(y)) for w, z in pairs_of_things with bind((h(w), k(z)) as (x, y)] ? This is a question about all the proposals for local binding, I think. Steve ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
Soni L. writes: > [(lambda y: (f(y), g(y)))(h(x)) for x in things] ? MicroLisp? ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
Robert Vanden Eynde wrote: The "make it a keyword in a context" might lead to things like "print(where where where = where)", not sure you'd want that :) What the heck, if it was good enough for PL/1... But that's just a choice of syntax, Choice of syntax is important, though. It's all very well to come up with an "insert syntax here" proposal that has some big obvious benefit, but if you can't actually come up with a pleasing syntax for it, then it won't fly. So it makes sense to consider potential syntaxes along with other aspects of a proposal. -- Greg ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
2018-03-03 8:40 GMT+01:00 Nick Coghlan : pairs = [(f(y), g(y)) for x in things with bind(h(x)) as y] I don't mucn like "with bind(h(x)) as y" because it's kind of like an abstraction inversion -- you're building something complicated on top of something complicated in order to get something simple, instead of just having the simple thing to begin with. If nothing else, it has a huge runtime cost for the benefit it gives. -- Greg ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
Robert Vanden Eynde wrote: But I think that the implementation of print(y with y = x + 1) would be more close to next(y for y in [ x+1 ]) WHy on earth should it be? Expanding that gives you a generator containing a loop that only executes once that is immediately run to yield exactly one value. Why bother with all that overhead? -- Greg ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
Nathan Goldbaum wrote: Where is also very common in numpy. So if someone did: from numpy import * data = where(condition) They might have issues Bummer, I didn't know numpy used it. That puts rather a big dampener on the idea of making it a keyword. :-( Remaining options include: * Make it a keyword only in certain contexts. That's been done before, but only as a temporary measure. Making it a permanent feature seems a bit hackish, and could cause problems for syntax highlighters. * Pick another word that isn't used often. My next choice would be "given", with maybe "letting" as a distant third. (Not just "let", because it doesn't read right after the expression.) * Re-use another keyword. Here "with" seems to be the best choice, but that would entail giving it two wildly different meanings. Guido probably isn't going to like that, since he has already expressed disapproval of doing it with "for". Some people thought Wirth was mad when he made all the keywords in Modula upper-case, but maybe he knew a thing or two. Going back further, Algol required all keywords to be marked specially in some way (that was left up to the implementation). If I ever design another language, I think I'm going to require the source to be HTML, and insist that all keywords be bold. -- Greg ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
Robert Vanden Eynde wrote: One could see : print(y with y = x+1) As a shortcut for : print(next(y for y in [ x+1 ])) Or more straightforwardly, print((lambda y: y)(x + 1)) This is how the semantics of let-type constructs is often defined in lambda-calculus-inspired languages such as Scheme and Haskell, and it suggests a viable implementation strategy. -- Greg ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
On Sat, Mar 3, 2018 at 5:12 AM Oleg Broytman wrote: > On Sat, Mar 03, 2018 at 02:36:39PM +1300, Greg Ewing < > greg.ew...@canterbury.ac.nz> wrote: > >[(f(y), g(y)) for x in things where y = h(x)] > > > > Possible objections to this: > > > > * Requires a new keyword, which may break existing code. > > > > - Yes, but "where" is an unlikely choice of name, being > > neither a noun, verb or adjective, so it probably wouldn't > > break very *much* code. > > ``where`` is a very popular name in code related to SQL. Take for > example ORMs: > > > https://github.com/sqlobject/sqlobject/search?l=Python&q=where&type=&utf8=%E2%9C%93 > > > https://github.com/zzzeek/sqlalchemy/search?l=Python&q=where&type=&utf8=%E2%9C%93 > Where is also very common in numpy. So if someone did: from numpy import * data = where(condition) They might have issues > > -- > > Greg > > Oleg. > -- > Oleg Broytmanhttp://phdru.name/p...@phdru.name >Programmers don't die, they just GOSUB without RETURN. > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
Le 3 mars 2018 08:45, "Nick Coghlan" a écrit : On 3 March 2018 at 11:36, Greg Ewing wrote: > 1. Name bindings local to an expression: > >roots = ([(-b-r)/(2*a), (-b+r)/(2*a)] where r = sqrt(b*b-4*a*c)) > > B. In an expression, surrounded by parentheses for > disambiguation. Bindings are visible only within the > parentheses. > I'll note that a significant benefit of this approach over the PEP 572 approach is that it would be amenable to a comprehension style scope-management solution: these expressions could create an implicitly nested function and immediately call it, just as 3.x comprehensions do. Adopting such an approach would *dramatically* lower the impact that hiding the bindings from the surrounding scope would have on the overall name resolution semantics. Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/ As I said, allowing this syntax (whether with a new keyword like 'where' or reusing something like 'with' to write print(y with y = x+1)) in any expression (not only after a "for" in a comprehension list) is useful only if a local scope is created (otherwise, it would be the same as simple assignement but in reverse ordre). One could see : print(y with y = x+1) As a shortcut for : print(next(y for y in [ x+1 ])) The same as this : [y for x in range(5) with y = x+1] being a shortcut for : [y for x in range(5) for y in [ x+1 ]] As said, allowing both use cases would lead to two different ways to write : [y for x in range(5) with y = x+1] vs [y with y = x+1 for x in range(5)] But that is not really an issue, it's logically different (is the y a conclusion of the iteration or a hidden lambda in the expression?). ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
On 2018-03-03 08:09 AM, Oleg Broytman wrote: On Sat, Mar 03, 2018 at 02:36:39PM +1300, Greg Ewing wrote: [(f(y), g(y)) for x in things where y = h(x)] Possible objections to this: * Requires a new keyword, which may break existing code. - Yes, but "where" is an unlikely choice of name, being neither a noun, verb or adjective, so it probably wouldn't break very *much* code. ``where`` is a very popular name in code related to SQL. Take for example ORMs: https://github.com/sqlobject/sqlobject/search?l=Python&q=where&type=&utf8=%E2%9C%93 https://github.com/zzzeek/sqlalchemy/search?l=Python&q=where&type=&utf8=%E2%9C%93 [(lambda y: (f(y), g(y)))(h(x)) for x in things] ? -- Greg Oleg. ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
On Sat, Mar 03, 2018 at 02:36:39PM +1300, Greg Ewing wrote: >[(f(y), g(y)) for x in things where y = h(x)] > > Possible objections to this: > > * Requires a new keyword, which may break existing code. > > - Yes, but "where" is an unlikely choice of name, being > neither a noun, verb or adjective, so it probably wouldn't > break very *much* code. ``where`` is a very popular name in code related to SQL. Take for example ORMs: https://github.com/sqlobject/sqlobject/search?l=Python&q=where&type=&utf8=%E2%9C%93 https://github.com/zzzeek/sqlalchemy/search?l=Python&q=where&type=&utf8=%E2%9C%93 > -- > Greg Oleg. -- Oleg Broytmanhttp://phdru.name/p...@phdru.name Programmers don't die, they just GOSUB without RETURN. ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
On 3 March 2018 at 07:45, Nick Coghlan wrote: > On 3 March 2018 at 11:36, Greg Ewing wrote: >> >> 1. Name bindings local to an expression: >> >>roots = ([(-b-r)/(2*a), (-b+r)/(2*a)] where r = sqrt(b*b-4*a*c)) >> >> B. In an expression, surrounded by parentheses for >> disambiguation. Bindings are visible only within the >> parentheses. > > > I'll note that a significant benefit of this approach over the PEP 572 > approach is that it would be amenable to a comprehension style > scope-management solution: these expressions could create an implicitly > nested function and immediately call it, just as 3.x comprehensions do. > Adopting such an approach would *dramatically* lower the impact that hiding > the bindings from the surrounding scope would have on the overall name > resolution semantics. While I'm *still* not sure any of this provides enough benefit to be worth doing, I will say that this proposal feels far less complicated than PEP 572. I don't particularly like the extension to if and while statements (and it's been mentioned that there are remarkably few cases where the value you want to capture is the actual condition rather than a value the condition tests) but otherwise I'm OK with it (call me -0 on the proposal without if/while, and -0.5 on the if/while part). Paul ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
On 3 March 2018 at 11:36, Greg Ewing wrote: > 1. Name bindings local to an expression: > >roots = ([(-b-r)/(2*a), (-b+r)/(2*a)] where r = sqrt(b*b-4*a*c)) > > B. In an expression, surrounded by parentheses for > disambiguation. Bindings are visible only within the > parentheses. > I'll note that a significant benefit of this approach over the PEP 572 approach is that it would be amenable to a comprehension style scope-management solution: these expressions could create an implicitly nested function and immediately call it, just as 3.x comprehensions do. Adopting such an approach would *dramatically* lower the impact that hiding the bindings from the surrounding scope would have on the overall name resolution semantics. Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
On 3 March 2018 at 11:36, Greg Ewing wrote: > PEP 572 as it stands seems to have many problems: > > * Asymmetry between the first and subsequent > uses of the bound value > * Embedded as-clauses are subtle and hard to spot > * Ever more convoluted semantics are being invented > to address percieved pitfalls > > Alternative proposal > > > Getting back to the original motivating use case of > intermediate values in comprehensions, to my mind there > is really only one clear and obvious way to write such > things: > >[(f(y), g(y)) for x in things where y = h(x)] > I know Guido is on record as not wanting to allow both "for name in sequence" and "for name = expr" due to that being a very subtle distinction between iteration and simple assignment (especially given that Julia uses them as alternate spellings for the same thing), but I'm wondering if it may be worth considering such a distinction in *with statements*, such that we allowed "with name = expr" in addition to "with cm as name" (where "name = expr" is just an ordinary assignment statement that doesn't trigger the context management protocol). The related enhancement to comprehensions would then be to allow with clauses to be interleaved between the for loops and the if statements, such that you could write things like: pairs = [(f(y), g(y)) for x in things with y = h(x)] contents = [f.read() for fname in filenames with open(fname) as f] while still preserving the property where comprehensions can be correctly interpreted just by converting each of the clauses to the corresponding statement form. Even without the "with name = expr" change, allowing with clauses in comprehensions would let you do (by way of a suitably defined "bind" CM): pairs = [(f(y), g(y)) for x in things with bind(h(x)) as y] Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
The syntax you propose is already in the Alternate syntax and there is an implementation at https://github.com/thektulu/cpython/tree/where-expr Already discussed, but no conclusion, for me I see two different proposals, the "[y for x in range(5) with y = x+1]" in comprehensions list, and the case in any expression "print (y with y = x+1)", as discussed the second case corresponds to a simple assignment so is less useful, but if the scope is local to the expression, that'd be useful : print(y with y = x+1); print(y) # NameError But I like it :) Le 3 mars 2018 02:36, "Greg Ewing" a écrit : > PEP 572 as it stands seems to have many problems: > > * Asymmetry between the first and subsequent > uses of the bound value > * Embedded as-clauses are subtle and hard to spot > * Ever more convoluted semantics are being invented > to address percieved pitfalls > > Alternative proposal > > > Getting back to the original motivating use case of > intermediate values in comprehensions, to my mind there > is really only one clear and obvious way to write such > things: > >[(f(y), g(y)) for x in things where y = h(x)] > > Possible objections to this: > > * Requires a new keyword, which may break existing code. > > - Yes, but "where" is an unlikely choice of name, being > neither a noun, verb or adjective, so it probably wouldn't > break very *much* code. In return, we get something that > resonates with language mathematicians have been using > for centuries, and a word that can be usefully googled. > > * Out-of-order evaluation > > - Comprehensions and if-expressions already have that. > > Extension to other use cases > > > There are some other situations in which it could be > useful to have a similar construct. > > 1. Name bindings local to an expression: > >roots = ([(-b-r)/(2*a), (-b+r)/(2*a)] where r = sqrt(b*b-4*a*c)) > > 2. Names bound as part of an expression and also available > in a following suite: > >if m where m = pattern.match(text): > do_something_with(m) > > There's a problem, though -- if "where" in an expression > creates bindings local to that expression, they're not > going to be visible in the rest of a comprehension or > compound statement. > > So I'm thinking that there would actually be three distinct > usages of "where": > > A. As a clause in a comprehension, where it creates bindings > local to the comprehension and is treated on the same footing > syntactically as "for" and "if" clauses. > > B. In an expression, surrounded by parentheses for > disambiguation. Bindings are visible only within the > parentheses. > > C. Following the expression of an "if" or "while" statement. > Bindings are visible within the preceding expression and the > following suite. > > Note that case B avoids the issue of whether expression-local > bindings affect the LHS of an assignment, because in > >a[x] = (x * 2 where x = 17) > > the "x" bound by the where-clause is clearly restricted to > the part in parentheses. This would be a syntax error: > >a[x] = x * 2 where x = 17# illegal > > -- > Greg > > > > > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings
PEP 572 as it stands seems to have many problems: * Asymmetry between the first and subsequent uses of the bound value * Embedded as-clauses are subtle and hard to spot * Ever more convoluted semantics are being invented to address percieved pitfalls Alternative proposal Getting back to the original motivating use case of intermediate values in comprehensions, to my mind there is really only one clear and obvious way to write such things: [(f(y), g(y)) for x in things where y = h(x)] Possible objections to this: * Requires a new keyword, which may break existing code. - Yes, but "where" is an unlikely choice of name, being neither a noun, verb or adjective, so it probably wouldn't break very *much* code. In return, we get something that resonates with language mathematicians have been using for centuries, and a word that can be usefully googled. * Out-of-order evaluation - Comprehensions and if-expressions already have that. Extension to other use cases There are some other situations in which it could be useful to have a similar construct. 1. Name bindings local to an expression: roots = ([(-b-r)/(2*a), (-b+r)/(2*a)] where r = sqrt(b*b-4*a*c)) 2. Names bound as part of an expression and also available in a following suite: if m where m = pattern.match(text): do_something_with(m) There's a problem, though -- if "where" in an expression creates bindings local to that expression, they're not going to be visible in the rest of a comprehension or compound statement. So I'm thinking that there would actually be three distinct usages of "where": A. As a clause in a comprehension, where it creates bindings local to the comprehension and is treated on the same footing syntactically as "for" and "if" clauses. B. In an expression, surrounded by parentheses for disambiguation. Bindings are visible only within the parentheses. C. Following the expression of an "if" or "while" statement. Bindings are visible within the preceding expression and the following suite. Note that case B avoids the issue of whether expression-local bindings affect the LHS of an assignment, because in a[x] = (x * 2 where x = 17) the "x" bound by the where-clause is clearly restricted to the part in parentheses. This would be a syntax error: a[x] = x * 2 where x = 17# illegal -- Greg ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/