Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings

2018-03-04 Thread Nathan Schneider
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

2018-03-04 Thread Chris Angelico
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

2018-03-04 Thread Mike Miller

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

2018-03-04 Thread Chris Angelico
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

2018-03-04 Thread Mike Miller


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

2018-03-04 Thread Robert Vanden Eynde
> 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

2018-03-04 Thread Robert Vanden Eynde
> 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

2018-03-04 Thread Robert Vanden Eynde
> 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

2018-03-04 Thread Stephen J. Turnbull
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

2018-03-04 Thread Stephen J. Turnbull
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

2018-03-03 Thread Greg Ewing

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 Thread Greg Ewing

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

2018-03-03 Thread Greg Ewing

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

2018-03-03 Thread Greg Ewing

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

2018-03-03 Thread Greg Ewing

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

2018-03-03 Thread Nathan Goldbaum
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

2018-03-03 Thread Robert Vanden Eynde
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

2018-03-03 Thread Soni L.



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

2018-03-03 Thread Oleg Broytman
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

2018-03-03 Thread Paul Moore
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

2018-03-02 Thread Nick Coghlan
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

2018-03-02 Thread Nick Coghlan
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

2018-03-02 Thread Robert Vanden Eynde
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

2018-03-02 Thread Greg Ewing

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/