Re: [Python-ideas] A comprehension scope issue in PEP 572

2018-05-10 Thread Tim Peters
...

[Guido]
>> You should really read Tim's initial post in this thread, where he
>> explains his motivation.

[Nick]
> I did, and then I talked him out of it by pointing out how confusing it
> would be to have the binding semantics of "x := y" be context dependent.

Ya, that was an effective Jedi mind trick when I was overdue to go to sleep ;-)

To a plain user, there's nothing about a listcomp or genexp that says
"new function introduced here".  It looks like, for all the world,
that it's running _in_ the block that contains it.  It's magical
enough that `for` targets magically become local.  But that's almost
never harmful magic, and often helpful, so worth it.


>...
> It *is* different, because ":=" normally binds the same as any other name
> binding operation including "for x in y:" (i.e. it creates a local
> variable), while at comprehension scope, the proposal has now become for "x
> := y" to create a local variable in the containing scope, while "for x in y"
> doesn't.

":=" target names in a genexp/listcmp are treated exactly the same as
any other non-for-target name:  they resolve to the same scope as they
resolve to in the block that contains them.  The only twist is that if
such a name `x` isn't otherwise known in the block, then `x` is
established as being local to the block (which incidentally also
covers the case when the genexp/listcomp is at module level, where
"local to the block" and "global to the block" mean the same thing).
Class scope may be an exception (I cheerfully never learned anything
about how class scope works, because I don't write insane code ;-) ).


> Comprehension scoping is already hard to explain when its just a
> regular nested function that accepts a single argument, so I'm not looking
> forward to having to explain that "x := y" implies "nonlocal x" at
> comprehension scope

It doesn't, necessarily.  If `x` is already known as `global` in the
block, then there's an implied `global x` at comprehension scope.

> (except that unlike a regular nonlocal declaration, it also implicitly makes 
> it a local
> in the immediately surrounding scope).

Only if `x` is otherwise _unknown_ in the block.  If, e.g., `x` is
already known in an enclosing scope E, then `x` also resolves to scope
E in the comprehension.  It is not made local to the enclosing scope
in that case.

I think it's more fruitful to explain the semantics than try to
explain a concrete implementation.  Python's has a "lumpy" scope
system now, with hard breaks among global scopes, class scopes, and
all other lexical scopes.  That makes implementations artificially
noisy to specify.  "resolve to the same scope as they resolve to in
the block that contains them, with a twist ..." avoids that noise
(e.g.,  the words "global" and "nonlocal" don't even occur), and gets
directly to the point:  in which scope does a name live?  If you think
it's already clear enough which  scope `y` resolves to in

z = (x+y for x in range(10))

then it's exactly as clear which scope `y` resolves to in

z = (x + (y := 7) for x in range(10))

with the twist that if `y` is otherwise unknown in the containing
block, `y` becomes local to the block.


> It isn't reasonable to wave this away as "It's only confusing to Nick
> because he's intimately familiar with how comprehensions are implemented",

As above, though, I'm gently suggesting that being so intimately
familiar with implementation details may be interfering with seeing
how all those details can _obscure_ rather than illuminate.  Whenever
you think you need to distinguish between, e.g., "nonlocal" and
"global", you're too deep in the detail weeds.


> as I also wrote some of the language reference docs for the current (already
> complicated) comprehension scoping semantics, and I can't figure out how
> we're going to document the proposed semantics in a way that will actually
> be reasonably easy for readers to follow.

Where are those docs?  I expect to find such stuff in section 4
("Execution model") of the Language Reference Manual, but listcomps
and genexps are only mentioned in passing once in the 3.6.5 section 4
docs, just noting that they don't always play well at class scope.


> ...
> - for comprehensions at class scope, the class scope is ignored for purposes
> of determining the target binding scope (and hence will implicitly create a
> new global variable when used in a top level class definition, and new
> function local when used in a class definition nested inside a function)

Isn't all of that too covered by "resolve to the same scope as they
resolve to in the block that contains them .."?  For example, in

class K:
print(g)

at module level, `g` obviously refers to the global `g`.  Therefore
any `g` appearing as a ";=" target in an immediately contained
comprehension also refers to the global `g`, exactly the same as if
`g` were any other non-for-target name in the comprehension.   That's
not a new rule:  it's a consequence of how class scopes 

Re: [Python-ideas] Inline assignments using "given" clauses

2018-05-10 Thread Nick Malaguti
Hi all. I've been lurking for a little while on this discussion and I
thought I might contribute some thoughts.
One of my  hurdles for ":=" is understanding when I should use it rather
than "=". Should I use it everywhere? Should I use it only where I can't
use regular "="? Is it a personal choice? Will it become so common that
I need to think harder because some people will use it really frequently
or intermix them?
I don't want to see "=" vs ":=" become like semicolons in JavaScript.
When I work on a different codebase, am I going to have to follow an
"always" or "never" for binding expressions? Maybe this is all overblown
and PEP8 direction will keep everyone on the same page, but I guess I
worry about there being 2 very similar, but not the same, ways to do it.
What I really like about "given" is it makes it a lot clearer when I
should use it. No one is going to want to write
x given x = f()

if they can just write

x = f()

If you need a binding expression in a comprehension or an if or while
statement, you'll know the pattern of using "given" to save that loop
and a half or to call a function and bind its result while iterating.
Just like you know when to use a ternary if to save that extra temporary
variable - there's little confusion about when to use a ternary,
especially since a few if statements quickly prove clearer to read.
10 if x == 5 else 9 if x == 2 else 8 if x == 3 else 100

looks much better as:

if x == 5:
result = 10
elif x == 2:
result = 9
elif x == 3:
result = 8
else:
result = 100

I feel the same way about given. If you feel tempted to go
overboard with:
x given x = y * 2 given y = z + 3 given z = f()

Which should be equivalent to:

x := (y := ((z := f()) + 3)) * 2

hopefully you'll think, "maybe I should just make 3 statements instead?"
And also I have no trouble following what that statement actually does
when using given. I didn't need any parenthesis to make sure I didn't
bind the wrong expressions and I don't have to read it from the inside
out. Each sub-expression is complete rather than being mixed together
(even though I have to read it from right to left).
I feel like the strongest argument for ":=" is for all the situations
where someone will actually want a binding expression in real code, ":="
is more succinct. I'm just concerned that when given a new binding
expression hammer, everything is going to look like a nail and all the
places where someone could really benefit from a binding expression will
be drowned out by the unnecessary usage of ":=" (and its side effects).
--
Nick

- Original message -
From: Guido van Rossum 
To: "marky1991 ." 
Cc: "python-ideas" 
Subject: Re: [Python-ideas] Inline assignments using "given" clauses
Date: Thu, 10 May 2018 11:10:50 -0400

Please no, it's not that easy. I can easily generate a stream of +1s or
-1s for any proposal. I'd need well-reasoned explanations and it would
have to come from people who are willing to spend significant time
writing it up eloquently. Nick has tried his best and failed to convince
me. So the bar is high.
(Also note that most of the examples that have been brought up lately
were meant to illustrate the behavior in esoteric corner cases while I
was working out the fine details of the semantics. Users should use this
feature sparingly and stay very far away of those corner cases -- but
they have to be specified in order to be able to implement this thing.)
On Thu, May 10, 2018 at 10:26 AM, marky1991 .  wrote:> If 
it just needs a stream of +1s, I personally like the "given"
> approach much more than the ":=" approach, for all of the many reasons
> repeated many times in the various email chains. (I preferred it as
> "as", but that's been struck down already) (and if it's between ":="
> and not having them at all, I would rather just not have them)


-- 
--Guido van Rossum (python.org/~guido)
_
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/
___
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] High Precision datetime

2018-05-10 Thread Nathaniel Smith
You don't mention the option of allowing time.microseconds to be a
float, and I was curious about that since if it did work, then that
might be a relatively smooth extension of the current API. The highest
value you'd store in the microseconds field is 1e6, and at values
around 1e6, double-precision floating point has precision of about
1e-10:

In [8]: 1e6 - np.nextafter(1e6, 0)
Out[8]: 1.1641532182693481e-10

So that could represent values to precision of ~0.116 femtoseconds, or
116 attoseconds. Too bad. Femtosecond precision would cover a lot of
cases, if you really need attoseconds then it won't work.

-n


On Thu, May 10, 2018 at 1:30 PM, Ed Page  wrote:
> Greetings,
>
> Is there interest in a PEP for extending time, datetime / timedelta for 
> arbitrary or extended precision fractional seconds?
>
> My company designs and manufactures scientific hardware that typically 
> operate with nanoseconds -- sometimes even attoseconds -- levels of 
> precision.  We’re in the process of providing Python APIs for some of these 
> products and need  to expose the full accuracy of the data to our customers.  
> Doing so would allow developers to do things like timestamp analog 
> measurements for correlating with other events in their system, or precisely 
> schedule a future time event for correctly interoperating  with other 
> high-speed devices.
>
> The API we’ve been toying with is adding two new fields to time, datetime and 
> timedelta
> - frac_seconds (int)
> - frac_seconds_exponent (int or new SITimeUnit enum)
>
> time.microseconds would be turned into a property that wraps frac_seconds for 
> compatibility
>
> Challenges
> - Defining the new `max` or `resolution`
> - strftime / strptime.  I propose that we do nothing, just leave formatting / 
> parsing to use `microseconds` at best.  On the other hand, __str__ could just 
> specify the fractional seconds using scientific or engineering notation.
>
> Alternatives
> - My company create our own datetime library
>   - Continued fracturing of time ... ecosystem (datetime, arrow, pendulum, 
> delorean, datetime64, pandas.Timestamp – all of which offer varying degrees 
> of compatibility)
> - Add an `attosecond` field and have `microsecond` wrap this.
>   - Effectively same except hard code `frac_seconds_exponent` to lowest value
>   - The most common cases (milliseconds, microseconds) will always pay the 
> cost of using a bigint as compared to the proposal which is a "pay for what 
> you use" approach
>   - How do we define what is "good enough" precision?
> - Continue to subdivide time by adding `nanosecond` that is "nanoseconds 
> since last micosecond", `picosecond` that is "picoseconds since last 
> micnanosecond", and  `attosecond` field that is "attoseconds since last 
> picosecond"
>   - Possibly surprising API; people might expect `picosecond` to be an offset 
> since last second
>   - Messy base 10 / base 2 conversions
> - Have `frac_seconds` be a float
>   - This has precision issues.
>
> If anyone wants to have an impromptu BoF on the subject, I'm available at 
> PyCon.
>
> Thanks
> Ed Page
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/



-- 
Nathaniel J. Smith -- https://vorpus.org
___
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] High Precision datetime

2018-05-10 Thread David Mertz
In fairness, Pandas, datetime64, and Arrow are really the same thing. I
don't know about Pendulum or Delorean. A common standard would be great, or
at least strong interoperability. I'm sure the authors of those projects
would want that... Arrow is entirely about interoperability, after all.

On Thu, May 10, 2018, 7:11 PM Ethan Furman  wrote:

> On 05/10/2018 10:30 AM, Ed Page wrote:
>
> > Alternatives
> > - My company create our own datetime library
> >- Continued fracturing of time ... ecosystem (datetime, arrow,
> pendulum, delorean, datetime64, pandas.Timestamp
>
> Or, team up with one of those (if you can).
>
> --
> ~Ethan~
>
>
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 572: about the operator precedence of :=

2018-05-10 Thread Greg Ewing

Tim Peters wrote:

Umm ... that's the opposite of what the Reference Manual says "lower":means:

"""
6.16. Operator precedence

The following table summarizes the operator precedence in Python, from
lowest precedence (least binding) to highest precedence (most
binding).
"""


Which is also in accord with the usual English meaning of the word
"precedence" -- things with higher precedence get done first.

--
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] High Precision datetime

2018-05-10 Thread Ethan Furman

On 05/10/2018 10:30 AM, Ed Page wrote:


Alternatives
- My company create our own datetime library
   - Continued fracturing of time ... ecosystem (datetime, arrow, pendulum, 
delorean, datetime64, pandas.Timestamp


Or, team up with one of those (if you can).

--
~Ethan~



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


Re: [Python-ideas] Sorry for yet another self discussion

2018-05-10 Thread Steven D'Aprano
On Thu, May 10, 2018 at 07:58:12PM +, stefano wrote:

> The disturbing part of the "self parameter" is the asymmetry of the
> definition and the call.

Why is that disturbing? There is always some asymmetry between 
*defining* a function and *calling* a function.

Function definitions:

def function(named parameter list):
block

Function calls:

function(positional arguments)


We don't repeat the keyword "def" or the colon in the call, and we 
obviously don't repeat the body of the block. We typically call the 
function with either positional arguments, or only a *subset* of the 
keyword arguments, relying on defaults to fill in the rest. The 
arguments we provide will often be expressions, sometimes complex 
expressions, not just simple names. Even if they are simple names, they 
rarely match the parameter name:

Definition:
function(spam, eggs, cheese=None, aardvark=True)

Call:
function((foo + bar) or baz, foobar)

So whatever symmetry there is, it isn't much.


> So I was thinking: why not do define the methods
> like: "def self.whatevermethod(par1, par2, etc)" instead of "def
> whatevermethod(self, par1, par2, etc)"?

"Why not ..." is the wrong question. Adding new features to the 
language, or new syntax, is not Default Allow ("add the feature, unless 
there is a compelling reason not to"). There has to be a good, 
positive reason for adding the feature, not merely a lack of reason 
not to.

What does this feature buy us? Not much.

It doesn't add any new expressiveness to the language. It doesn't let 
the language do anything that couldn't be done before.

What it does do is add complexity to the syntax, there now being two 
ways to specify the first parameter:

def self.method(arg)
def method(self, arg)

both of which need to be supported, which means more complexity to the 
language, more documentation needed, more for people to learn, more for 
tutorials to have to cover, more tests needed, etc, and all those costs 
don't actually gain us any significant advantage for the code we write.

And what happens with classmethods and staticmethods, or those people 
who for whatever reason refuse to use the name "self" for the first 
parameter?


-- 
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] High Precision datetime

2018-05-10 Thread Alexander Belopolsky
> Is there interest in a PEP for extending time, datetime / timedelta for
arbitrary or extended precision fractional seconds?

Having seen the utter disaster that similar ideas brought to numpy, I would
say: no.

On the other hand, nanoseconds are slowly making their way to the stdlib
and to add nanoseconds to datetime we only need a fully backward compatible
implementation, not even a PEP.

See .
___
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] A comprehension scope issue in PEP 572

2018-05-10 Thread Tim Peters
[Tim]
>> ...
>> So long as I'm the only one looking at real-life use cases, mine is
>> the only evidence I care about ;-)  I don't really care about
>> contrived examples, unless they illustrate that a proposal is
>> ill-defined, impossible to implement as intended, or likely to have
>> malignant unintended consequences out-weighing their benefits.

[Brendan Barnwell ]
> You keep saying things like this with a smiley, and I realize you
> know what you're talking about (much more than I do), but I'd just like to
> push back a bit against that entire concept.

I'm not so keen on meta-discussions either ;-)


> Number one, I think many people have been bringing in real life uses
> cases.

Keep in mind the context here:  _this_ thread is specifically about
listcomps and genexps.  I agree there have been tons of use cases
presented for statement-oriented applications (some positive for the
feature, some negative), but not so much for listcomps and genexps.

It's worth noting again that "the" use case that started all this long
ago was a listcomp that the current PEP points out still "won't work":

total = 0
progressive_sums = [total := total + value for value in data]

It's obvious what that's intended to do.  It's not obvious why it
blows up.  It's a question of scope, and the scopes of names in
synthesized functions is a thoroughly legitimate thing to question.
The suggestion made in the first message of this thread was the
obvious scope change needed to make that example work, although I was
motivated by looking at _other_ listcomp/genexp use cases.  They
wanted the same scope decision as the example above.  But I didn't
realize that the example above was essentially the same thing until
after I made the suggestion.


>  Number two, I disagree with the idea that looking at individual use
> cases and ignoring logical argumentation is the way to go.

Fine, then you argue, and I'll look at use cases ;-)  Seriously, I
don't at all ignore argument - but, yes, arguments are secondary to
me.  I don't give a rip about how elegant something is if it turns out
to be unusable.  Conversely, I don't _much_ care about how "usable"
something is if the mental model for how it works is inexplicable.


> The problem with it is that a lot of the thorny issues arise in
> unanticipated interactions between constructs that were
> designed to handle separate use cases.

Sure.


> I also do not think it's appropriate to say "if it turns out there's
> a weird interaction between two features, then just don't use those two
> things together".

Sometimes it is, sometimes it isn't.  For example, code using threads
has to be aware of literal mountains of other features that may not
work well (or at all) in a multi-threaded environment without major
rewriting.  Something as simple as "count += 1" may fail in mysterious
ways otherwise.  So it goes.  But note that this is easily
demonstrated by realistic code.


> One of the great things about Python's design is that it doesn't just
> make it easy for us to write good code, but in many ways makes
> it difficult for us to write bad code.

That one I disagree with.  It's very easy to write bad code in every
language I'm aware of.  It's just that Python programmers are too
enlightened to approve of doing so ;-)


>  It is absolutely a good idea to think of the broad range of wacky things that
> COULD be done with a feature,

So present some!

> not just the small range of things in the focal area of its intended use.
> We may indeed decide that some of the wacky cases are so unlikely that we're
> willing to accept them, but we can only decide that after we consider them.
> You seem to be suggesting that we shouldn't even bother thinking about such
> corner cases at all, which I think is a dangerous mistake.

To the contrary, bring 'em on.  But there is no feature in Python you
can't make "look bad" by contriving examples, from two-page regular
expressions to `if` statements nested 16 deep.  "But no sane person
would do that" is usually - but not always - "refutation" enough for
such stuff.


> Taking the approach of "this individual use case justifies this
> individual feature", leads to things like JavaScript, a hellhole of special
> cases, unintended consequences, and incoherence between different corners of
> the language.  There are real cognitive benefits to having language features
> make logical and conceptual sense IN ADDITION TO having practical utility,
> and fit together into a unified whole.

I haven't ignored that here.  The scope rule for synthesized functions
implementing regexps and listcomps _today_ is:

 The names local to that function are the names appearing as `for` targets.
 All other names resolve to the same scopes they resolve to in the block
 containing the synthesized function.

The scope rule if the suggestion is adopted?  The same, along with
that a name appearing as a ":=" target 

Re: [Python-ideas] Inline assignments using "given" clauses

2018-05-10 Thread Nick Coghlan
On 10 May 2018 at 11:10, Guido van Rossum  wrote:

> Please no, it's not that easy. I can easily generate a stream of +1s or
> -1s for any proposal. I'd need well-reasoned explanations and it would have
> to come from people who are willing to spend significant time writing it up
> eloquently. Nick has tried his best and failed to convince me. So the bar
> is high.
>
> (Also note that most of the examples that have been brought up lately were
> meant to illustrate the behavior in esoteric corner cases while I was
> working out the fine details of the semantics. Users should use this
> feature sparingly and stay very far away of those corner cases -- but they
> have to be specified in order to be able to implement this thing.)
>

I raised this with some of the folks that were still here at the Education
Summit (similar to what I did for data classes at the PyCon Australia
education seminar last year), but whereas the reactions to data classes
were "as easy or easier to teach as traditional classes", the reaction for
this for the folks that I asked was almost entirely negative - the most
positive reaction was "Yes, if it's as a wholesale replacement for the '='
spelling, since that sometimes gets confused with mathematical equality".
As an *addition* to the existing spelling, and especially with the now
proposed leaking semantics in comprehension scopes, it was "No, that would
just confuse out students".

It's one thing adding syntactic and semantic complexity for the sake of
something that significantly increases the language's expressive power
(which is what the original sublocal scopes proposal was aiming for: the
ability to more readily express constrained scoping and name shadowing
without explicit name aliasing and del statements), it's something else
entirely to do it for the sake of purely cosmetic tweaks like flattening
the occasional nested if-else chain or replacing a loop-and-a-half with an
embedded assignment.

Regards,
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] Inline assignments using "given" clauses

2018-05-10 Thread Kirill Balunov
2018-05-10 16:44 GMT+03:00 Guido van Rossum :

> I'm sorry, but unless there's a sudden landslide of support for 'given' in
> favor of ':=', I'm really not going to consider it.
>
> I'd pronounce "if (x := y) > 0" as either "if y (assigned to x) is greater
> than zero" or "if x (assigned from y) is greater than zero".
>


I think you do not quite objectively look at the current situation. Many
just lost interest in attempts to move the topic at least a little bit in
the other way, seeing how you and Tim so actively expresses
support/protects this `:=` syntax, while ignoring or pushing out
alternative opinions :-). Of course, the latter is partly due to the
incredible number of different threads and messages on this topic.

Briefly:

Initially, the main argument in favor of `:=` was that this form is similar
to the usual assignment statement, but can be used as an expression. Ok.

Then everyone agreed with the idea that it's necessary to limit assignment
target to name only. Although all this criticism was actually put forward
in the first 50-100 messages on the topic.

In the same first hundred it was actively discussed, that in fact, this
idea gives a win only in `while` and `if` statemetns that probably will
match 99%+ where it will be used for its intended purpose. At the same
time, most of the criticism concerned exactly the use in generators and
comprehenshions, they are already often overloaded for perception. And as
you once said - "Language Design Is Not Just Solving Puzzles".

There was also discussed the difference in perception between the `expr op
name` and `name op expr`. Here the expression is something that is
important, the name is only a convenient consequence.

At the moment with all the constraints of `:=`, the discuscation is more
like - trying to cram this syntax into the language. While for those who
are familiar with Pascal, Icon and other languages that use this syntax,
this - `:=` looks natural. For others and I believe such a majority among
users, this syntax is, to put it mildly, not natural and ugly producing a
line noise, the colon `:` symbol is already used in a lot of places.

With all the changes, the limitations and magic with scopes. Is it now
easier to explain all the differences between `=` and `:=`, than the
difference between `if expr as name ...: ...` and `with expr as name:`?

Therefore, I take Nick's insistent position as an attempt to at least
somehow make an alternative look at this topic.


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


Re: [Python-ideas] Inline assignments using "given" clauses

2018-05-10 Thread Terry Reedy

On 5/10/2018 9:44 AM, Guido van Rossum wrote:
I'm sorry, but unless there's a sudden landslide of support for 'given' 
in favor of ':=', I'm really not going to consider it.


I'd pronounce "if (x := y) > 0" as either "if y (assigned to x) is 
greater than zero" or "if x (assigned from y) is greater than zero".


or "if x (bound to y) is greater than zero" ("do something with x").

--
Terry Jan Reedy

___
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] Inline assignments using "given" clauses

2018-05-10 Thread David Mertz
Only the BDFL has a vote with non-zero weight.

But I'll contribute my zero-weighted preference for :=.


On Thu, May 10, 2018, 4:01 PM Ryan Gonzalez  wrote:

> Probably going to completely lose this, but would it be possible to have a
> vote? +1 for either 'given' and/or ':='?
>
> On Thu, May 10, 2018 at 2:48 PM Guido van Rossum  wrote:
>
>> Yes.
>>
>> On Thu, May 10, 2018, 13:18 Alexander Belopolsky <
>> alexander.belopol...@gmail.com> wrote:
>>
>>> On Thu, May 10, 2018 at 9:44 AM, Guido van Rossum 
>>> wrote:
>>> > I'm sorry, but unless there's a sudden landslide of support for
>>> 'given' in
>>> > favor of ':=', I'm really not going to consider it.
>>>
>>> How much support was there for ":="?  Are you serious about bringing
>>> back Pascal and Algol from their comfortable resting places?
>>>
>> ___
>> Python-ideas mailing list
>> Python-ideas@python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
>
> --
> Ryan (ライアン)
> Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
> https://refi64.com/
> ___
> 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] PEP 572: about the operator precedence of :=

2018-05-10 Thread Terry Reedy

On 5/10/2018 9:53 AM, Guido van Rossum wrote:
On Thu, May 10, 2018 at 3:32 AM, Terry Reedy 
> wrote:


On 5/9/2018 11:33 PM, Guido van Rossum wrote:

I now think that the best way out is to rule `:=` in the top
level expression of an expression statement completely


I would like to be able to interactively enter

 >>> a: = f(2,4)

to have 'a' echoed as well as bound.


I hope that's a typo (the can be no space between `:` and `=`, since 
`:=` is a single token, just like `<=').


a := f(2,4) # corrected ;-)

We *could* make this work while still ruling out the ambiguous cases 
(which involve top-level commas on either side of the assignment 
expression).


OTOH I worry that this particular feature would cause `:=` to become 
part of many a teacher's bag of tricks to show off,


until someone tries a := [0]*1000


exposing users to it way too early for any curriculum, > and it might then 
elicit complaints that


def f():

... a := 5
...

f()



doesn't print `5`.


Although the reason the same as for any expression, I can believe that 
people will see it as different.  A bare assignment expression *looks* 
like a statement in a way that other expressions do not.
So all in all I'm not sure I think this is important enough to support, 
and the rule "Use `:=` in expressions, not as a top level assignment" 
seems easier to explain and understand.


--
Terry Jan Reedy


___
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] Have a "j" format option for lists

2018-05-10 Thread David Mertz
-1 on idea. Far too many edge cases that can't be handled... Or absurd
complexity added to format mini-language if it tries to handle them (and
still fails).

On Thu, May 10, 2018, 3:57 PM Eric V. Smith  wrote:

> On 5/10/18 12:28 PM, Facundo Batista wrote:
> > 2018-05-10 10:34 GMT-03:00 Chris Angelico :
> >
> >>>
> >>> Ideally, it will handle *any* iterable.
> >>
> >> If it's to handle arbitrary iterables, it can't be the normal style of
> >> "take this string, pass it to the object's __format__ method, and let
> >> it interpret it". That's why I suggested a bang notation instead. We
> >> have some already:
> >
> > Yes, I think it fits better, as it's not just a formatting, it's more
> > an "operation"...
> >
> >>  A "!j" flag
> >> could take an iterable, format each element using the given format,
> >> and then join them. The letter "j" makes good sense then, as it
> >
> > Where would you indicate the separator if we use the bang notation?
>
> You would have to wedge it in before the colon. Something like:
>
> f'{lst!j, :20}'
>
> But then you couldn't have a colon in the separator. And this would be
> our first conversion character to be more than a single character.
>
> I'm opposed to this proposal. Just call str.join(), or write a helper
> function or class (depending on what you're trying to do). It's not
> worth complicating what's already a complicated topic.
>
> Eric
> ___
> 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] Inline assignments using "given" clauses

2018-05-10 Thread Ryan Gonzalez
Probably going to completely lose this, but would it be possible to have a
vote? +1 for either 'given' and/or ':='?

On Thu, May 10, 2018 at 2:48 PM Guido van Rossum  wrote:

> Yes.
>
> On Thu, May 10, 2018, 13:18 Alexander Belopolsky <
> alexander.belopol...@gmail.com> wrote:
>
>> On Thu, May 10, 2018 at 9:44 AM, Guido van Rossum 
>> wrote:
>> > I'm sorry, but unless there's a sudden landslide of support for 'given'
>> in
>> > favor of ':=', I'm really not going to consider it.
>>
>> How much support was there for ":="?  Are you serious about bringing
>> back Pascal and Algol from their comfortable resting places?
>>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
Ryan (ライアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
___
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] Sorry for yet another self discussion

2018-05-10 Thread stefano
I know that "self" parameter have been discussed a lot, but still I didn't
find this proposal. If it was instead take my sincere apologies and please
forget this mail.

The disturbing part of the "self parameter" is the asymmetry of the
definition and the call. So I was thinking: why not do define the methods
like: "def self.whatevermethod(par1, par2, etc)" instead of "def
whatevermethod(self, par1, par2, etc)"?

This will allow the call and the definition to be written exactly in the
same way, still leaving the "clarity" of the additional input for the
function. Moreover this can be made backward compatible (even still without
making self a reserved word, to be considered anyway).

I've been short by purpose but ready to elaborate if needed.

Thank you for the attention.

_Stefano
___
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] Have a "j" format option for lists

2018-05-10 Thread Eric V. Smith

On 5/10/18 12:28 PM, Facundo Batista wrote:

2018-05-10 10:34 GMT-03:00 Chris Angelico :



Ideally, it will handle *any* iterable.


If it's to handle arbitrary iterables, it can't be the normal style of
"take this string, pass it to the object's __format__ method, and let
it interpret it". That's why I suggested a bang notation instead. We
have some already:


Yes, I think it fits better, as it's not just a formatting, it's more
an "operation"...


 A "!j" flag
could take an iterable, format each element using the given format,
and then join them. The letter "j" makes good sense then, as it


Where would you indicate the separator if we use the bang notation?


You would have to wedge it in before the colon. Something like:

f'{lst!j, :20}'

But then you couldn't have a colon in the separator. And this would be 
our first conversion character to be more than a single character.


I'm opposed to this proposal. Just call str.join(), or write a helper 
function or class (depending on what you're trying to do). It's not 
worth complicating what's already a complicated topic.


Eric
___
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] Inline assignments using "given" clauses

2018-05-10 Thread Guido van Rossum
Yes.

On Thu, May 10, 2018, 13:18 Alexander Belopolsky <
alexander.belopol...@gmail.com> wrote:

> On Thu, May 10, 2018 at 9:44 AM, Guido van Rossum 
> wrote:
> > I'm sorry, but unless there's a sudden landslide of support for 'given'
> in
> > favor of ':=', I'm really not going to consider it.
>
> How much support was there for ":="?  Are you serious about bringing
> back Pascal and Algol from their comfortable resting places?
>
___
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] High Precision datetime

2018-05-10 Thread Guido van Rossum
I have to agree with David that this seems too specialized to make room for
in the stdlib.

On Thu, May 10, 2018, 15:16 David Mertz  wrote:

> This feels specialized enough to belong in a third party library. If that
> library can behave as transparently as possible interacting with Python
> datetime, so much the better. But the need is niche enough I don't think it
> belongs in standard library.
>
> ... this as someone who actually worked in a lab that measured MD
> simulations in attoseconds. I do understand the purpose.
>
> On Thu, May 10, 2018, 2:00 PM Ed Page  wrote:
>
>> Greetings,
>>
>> Is there interest in a PEP for extending time, datetime / timedelta for
>> arbitrary or extended precision fractional seconds?
>>
>> My company designs and manufactures scientific hardware that typically
>> operate with nanoseconds -- sometimes even attoseconds -- levels of
>> precision.  We’re in the process of providing Python APIs for some of these
>> products and need  to expose the full accuracy of the data to our
>> customers.  Doing so would allow developers to do things like timestamp
>> analog measurements for correlating with other events in their system, or
>> precisely schedule a future time event for correctly interoperating  with
>> other high-speed devices.
>>
>> The API we’ve been toying with is adding two new fields to time, datetime
>> and timedelta
>> - frac_seconds (int)
>> - frac_seconds_exponent (int or new SITimeUnit enum)
>>
>> time.microseconds would be turned into a property that wraps frac_seconds
>> for compatibility
>>
>> Challenges
>> - Defining the new `max` or `resolution`
>> - strftime / strptime.  I propose that we do nothing, just leave
>> formatting / parsing to use `microseconds` at best.  On the other hand,
>> __str__ could just specify the fractional seconds using scientific or
>> engineering notation.
>>
>> Alternatives
>> - My company create our own datetime library
>>   - Continued fracturing of time ... ecosystem (datetime, arrow,
>> pendulum, delorean, datetime64, pandas.Timestamp – all of which offer
>> varying degrees of compatibility)
>> - Add an `attosecond` field and have `microsecond` wrap this.
>>   - Effectively same except hard code `frac_seconds_exponent` to lowest
>> value
>>   - The most common cases (milliseconds, microseconds) will always pay
>> the cost of using a bigint as compared to the proposal which is a "pay for
>> what you use" approach
>>   - How do we define what is "good enough" precision?
>> - Continue to subdivide time by adding `nanosecond` that is "nanoseconds
>> since last micosecond", `picosecond` that is "picoseconds since last
>> micnanosecond", and  `attosecond` field that is "attoseconds since last
>> picosecond"
>>   - Possibly surprising API; people might expect `picosecond` to be an
>> offset since last second
>>   - Messy base 10 / base 2 conversions
>> - Have `frac_seconds` be a float
>>   - This has precision issues.
>>
>> If anyone wants to have an impromptu BoF on the subject, I'm available at
>> PyCon.
>>
>> Thanks
>> Ed Page
>> ___
>> 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 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] High Precision datetime

2018-05-10 Thread David Mertz
This feels specialized enough to belong in a third party library. If that
library can behave as transparently as possible interacting with Python
datetime, so much the better. But the need is niche enough I don't think it
belongs in standard library.

... this as someone who actually worked in a lab that measured MD
simulations in attoseconds. I do understand the purpose.

On Thu, May 10, 2018, 2:00 PM Ed Page  wrote:

> Greetings,
>
> Is there interest in a PEP for extending time, datetime / timedelta for
> arbitrary or extended precision fractional seconds?
>
> My company designs and manufactures scientific hardware that typically
> operate with nanoseconds -- sometimes even attoseconds -- levels of
> precision.  We’re in the process of providing Python APIs for some of these
> products and need  to expose the full accuracy of the data to our
> customers.  Doing so would allow developers to do things like timestamp
> analog measurements for correlating with other events in their system, or
> precisely schedule a future time event for correctly interoperating  with
> other high-speed devices.
>
> The API we’ve been toying with is adding two new fields to time, datetime
> and timedelta
> - frac_seconds (int)
> - frac_seconds_exponent (int or new SITimeUnit enum)
>
> time.microseconds would be turned into a property that wraps frac_seconds
> for compatibility
>
> Challenges
> - Defining the new `max` or `resolution`
> - strftime / strptime.  I propose that we do nothing, just leave
> formatting / parsing to use `microseconds` at best.  On the other hand,
> __str__ could just specify the fractional seconds using scientific or
> engineering notation.
>
> Alternatives
> - My company create our own datetime library
>   - Continued fracturing of time ... ecosystem (datetime, arrow, pendulum,
> delorean, datetime64, pandas.Timestamp – all of which offer varying degrees
> of compatibility)
> - Add an `attosecond` field and have `microsecond` wrap this.
>   - Effectively same except hard code `frac_seconds_exponent` to lowest
> value
>   - The most common cases (milliseconds, microseconds) will always pay the
> cost of using a bigint as compared to the proposal which is a "pay for what
> you use" approach
>   - How do we define what is "good enough" precision?
> - Continue to subdivide time by adding `nanosecond` that is "nanoseconds
> since last micosecond", `picosecond` that is "picoseconds since last
> micnanosecond", and  `attosecond` field that is "attoseconds since last
> picosecond"
>   - Possibly surprising API; people might expect `picosecond` to be an
> offset since last second
>   - Messy base 10 / base 2 conversions
> - Have `frac_seconds` be a float
>   - This has precision issues.
>
> If anyone wants to have an impromptu BoF on the subject, I'm available at
> PyCon.
>
> Thanks
> Ed Page
> ___
> 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] Have a "j" format option for lists

2018-05-10 Thread Serhiy Storchaka

09.05.18 15:39, Facundo Batista пише:

authors = ["John", "Mary", "Estela"]
"Authors: {:, j}".format(authors)

'Authors: John, Mary, Estela'


In the case of the list of book or article authors it would be better to 
get "John, Mary and Estela" or "John, Mary, and Estela". In other cases 
"John, Mary & Estela" can be more appropriate.


I mean that in real case you will need to use an external function that 
implements more complex algorithm for formatting a list.


___
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] A comprehension scope issue in PEP 572

2018-05-10 Thread Brendan Barnwell

On 2018-05-10 11:05, Tim Peters wrote:

So long as I'm the only one looking at real-life use cases, mine is
the only evidence I care about ;-)  I don't really care about
contrived examples, unless they illustrate that a proposal is
ill-defined, impossible to implement as intended, or likely to have
malignant unintended consequences out-weighing their benefits.


	You keep saying things like this with a smiley, and I realize you know 
what you're talking about (much more than I do), but I'd just like to 
push back a bit against that entire concept.


	Number one, I think many people have been bringing in real life uses 
cases.  Number two, I disagree with the idea that looking at individual 
use cases and ignoring logical argumentation is the way to go.  The 
problem with it is that a lot of the thorny issues arise in 
unanticipated interactions between constructs that were designed to 
handle separate use cases.


	I also do not think it's appropriate to say "if it turns out there's a 
weird interaction between two features, then just don't use those two 
things together".  One of the great things about Python's design is that 
it doesn't just make it easy for us to write good code, but in many ways 
makes it difficult for us to write bad code.  It is absolutely a good 
idea to think of the broad range of wacky things that COULD be done with 
a feature, not just the small range of things in the focal area of its 
intended use.  We may indeed decide that some of the wacky cases are so 
unlikely that we're willing to accept them, but we can only decide that 
after we consider them.  You seem to be suggesting that we shouldn't 
even bother thinking about such corner cases at all, which I think is a 
dangerous mistake.


	Taking the approach of "this individual use case justifies this 
individual feature", leads to things like JavaScript, a hellhole of 
special cases, unintended consequences, and incoherence between 
different corners of the language.  There are real cognitive benefits to 
having language features make logical and conceptual sense IN ADDITION 
TO having practical utility, and fit together into a unified whole.


	Personally my feeling on this whole thread is that these changes, if 
implemented are likely to decrease the average readability of Python 
code, and I don't see the benefits as being worth the added complexity.


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

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


Re: [Python-ideas] A comprehension scope issue in PEP 572

2018-05-10 Thread Tim Peters
Just a quickie - I'm out of time for now.

[Guido]
>> That's just one of several "don't do that" situations. *What will happen*
>> is perhaps hard to see at a glance, but it's perfectly well specified. Not
>> all legal code does something useful though, and in this case the obvious
>> advice should be to use different variables.

[Nick]
> I can use that *exact same argument* to justify the Python 2 comprehension
> variable leaking behaviour. We decided that was a bad idea based on ~18
> years of experience with it,

Here's the practical difference:  you can't write a listcomp or genexp
AT ALL without a "for" clause, so whether "for" target names leak is
an issue in virtually every listcomp or genexp ever written.  Here's
one where it isn't:

[None for somelist[12] in range(10)]

Which nobody has ever seen in real life ;-)

But ":=" is never required to write one - you only use it when you go
out of your way to use it.  I expect that will be relatively rare in
real life listcomps and genexps.


> and there hasn't been a clear justification presented for going back on that
> decision

Nobody is suggesting going back on "all and only `for` target names
are local to the genexp/listcomp".  To the contrary,  the proposal
preserves that verbatim:  It's not _adding_ "oh, ya, and binding
operator targets are local too".  Just about everything here follows
from _not_ adding that.


> presented beyond "Tim would like using it sometimes".

So long as I'm the only one looking at real-life use cases, mine is
the only evidence I care about ;-)  I don't really care about
contrived examples, unless they illustrate that a proposal is
ill-defined, impossible to implement as intended, or likely to have
malignant unintended consequences out-weighing their benefits.
___
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] High Precision datetime

2018-05-10 Thread Ed Page
Greetings,
 
Is there interest in a PEP for extending time, datetime / timedelta for 
arbitrary or extended precision fractional seconds?
 
My company designs and manufactures scientific hardware that typically operate 
with nanoseconds -- sometimes even attoseconds -- levels of precision.  We’re 
in the process of providing Python APIs for some of these products and need  to 
expose the full accuracy of the data to our customers.  Doing so would allow 
developers to do things like timestamp analog measurements for correlating with 
other events in their system, or precisely schedule a future time event for 
correctly interoperating  with other high-speed devices. 
 
The API we’ve been toying with is adding two new fields to time, datetime and 
timedelta
- frac_seconds (int)
- frac_seconds_exponent (int or new SITimeUnit enum)
 
time.microseconds would be turned into a property that wraps frac_seconds for 
compatibility
 
Challenges
- Defining the new `max` or `resolution`
- strftime / strptime.  I propose that we do nothing, just leave formatting / 
parsing to use `microseconds` at best.  On the other hand, __str__ could just 
specify the fractional seconds using scientific or engineering notation.
 
Alternatives
- My company create our own datetime library
  - Continued fracturing of time ... ecosystem (datetime, arrow, pendulum, 
delorean, datetime64, pandas.Timestamp – all of which offer varying degrees of 
compatibility)
- Add an `attosecond` field and have `microsecond` wrap this.
  - Effectively same except hard code `frac_seconds_exponent` to lowest value
  - The most common cases (milliseconds, microseconds) will always pay the cost 
of using a bigint as compared to the proposal which is a "pay for what you use" 
approach
  - How do we define what is "good enough" precision?
- Continue to subdivide time by adding `nanosecond` that is "nanoseconds since 
last micosecond", `picosecond` that is "picoseconds since last micnanosecond", 
and  `attosecond` field that is "attoseconds since last picosecond"
  - Possibly surprising API; people might expect `picosecond` to be an offset 
since last second
  - Messy base 10 / base 2 conversions
- Have `frac_seconds` be a float
  - This has precision issues.
 
If anyone wants to have an impromptu BoF on the subject, I'm available at PyCon.

Thanks
Ed Page
___
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] A comprehension scope issue in PEP 572

2018-05-10 Thread Tim Peters
[Nick Coghlan  ]
> How would you expect this to work in cases where the generator expression
> isn't immediately consumed? If "p" is nonlocal (or global) by default, then
> that opens up the opportunity for it to be rebound between generator steps.
> That gets especially confusing if you have multiple generator expressions in
> the same scope iterating in parallel using the same binding target:

I'm most interested in what sensible programmers can do easily that's
of use, not really about  pathologies that can be contrived.

> # This is fine
> gen1 = (p for p in range(10))
> gen2 = (p for p in gen1)
> print(list(gen2))

Sure.

>
> # This is not (given the "let's reintroduce leaking from comprehensions" 
> proposal)

Be fair:  it's not _re_introducing anything.  It's brand new syntax
for which "it's a very much intended feature" that a not-local name
can be bound.  You have to go out of your way to use it.  Where it
doesn't do what you want, don't use it.

> p = 0

I'm not sure of the intent of that line.  If `p` is otherwise unknown
in this block, its appearance as a binding operator target in an
immediately contained genexp establishes that `p` is local to this
block.  So `p = 0` here just establishes that directly.  Best I can
guess, the 0 value is never used below.

> gen1 = (p := q for q in range(10))

I expect that's a compile time error, grouping as

gen1 = (p := (q for q in range(10)))

but without those explicit parentheses delimiting the "genexp part" it
may not be _recognized_ as being a genexp.  With the extra parens, it
binds both `gen1` and `p` to the genexp, and `p` doesn't appear in the
body of the genexp at all.  Or did you intend

gen1 = ((p := q) for q in range(10))

?  I'll assume that's so.


> gen2 = (p, p := q for q in gen1)

OK, I really have no guess about the intent there.  Note that

gen2 = (p, q for q in gen1)

is a syntax error today, while

gen2 = (p, (q for q in gen1))

builds a 2-tuple.  Perhaps

gen2 = ((p, p := q) for q in gen1)

was intended?

Summarizing:

gen1 = ((p := q) for q in range(10))
gen2 = ((p, p := q) for q in gen1)

is my best guess.

> print(list(gen2))

[(0, 0), (1, 1), (2, 2), ..., (9, 9)]

But  let's not pretend it's impossible to do that today; e.g., this
code produces the same:

class Cell:
def __init__(self, value=None):
self.bind(value)
def bind(self, value):
self.value = value
return value

p = Cell()
gen1 = (p.bind(q) for q in range(10))
gen2 = ((p.value, p.bind(q)) for q in gen1)
print(list(gen2))

Someone using ":=" INTENDS to bind the name, just as much as someone
deliberately using that `Cell` class.

> It also reintroduces the original problem that comprehension scopes solved,
> just in a slightly different form:
>
> # This is fine
> for x in range(10):
> for y in range(10):
> transposed_related_coords = [y, x for x, y in related_coords(x, 
> y)]

I'm not clear on what "This is fine" means, other than that the code
does whatever it does.  That's part of why I so strongly prefer
real-life use cases.  In the code above, I can't imagine what the
intent of the code might be _unless_ they're running tons of
otherwise-useless code for _side effects_ performed by calling
`related_coords()`.  If "it's functional", they could do the same via

x = y = 9
transposed_related_coords = [y, x for x, y in related_coords(x, y)]

except that's a syntax error ;-)  I assume

transposed_related_coords = [(y, x) for x, y in related_coords(x, y)]

was intended.

BTW, I'd shoot anyone who tried to check in that code today ;-)  It
inherently relies on that the name `x` inside the listcomp refers to
two entirely different scopes, and that's Poor Practice (the `x` in
the `related_coords()` call refers to the `x` in `for x in range(10)`,
but all other instances of `x` refer to the listcomp-local `x`).


> # This is not (given the "let's reintroduce leaking from comprehensions" 
> proposal)
> for x in range(10):
> for y in range(10):
> related_interesting_coords = [x, y for x in related_x_coord(x, y)
> if 
> is_interesting(y := f(x))]

Same syntax error there (you need parens around "x, y" at the start of
the listcomp).

Presumably they _intended_ to build (x, f(x)) pairs when and only when
`f(x)` "is interesting".  In what specific way does the code fail to
do that?  Yes, the outer `y` is rebound, but what of it?  When the
statement completes, `y` will be rebound to the next value from the
inner range(10), and that's the value of `y` seen by
`related_x_coord(x, y)` the next time the loop body runs.  The binding
done by `:=` is irrelevant to that.

So I don't see your point in that specific example, although - sure! -
of course it's possible to contrive examples where it really would
matter.  

Re: [Python-ideas] Have a "j" format option for lists

2018-05-10 Thread Chris Angelico
On Fri, May 11, 2018 at 2:28 AM, Facundo Batista
 wrote:
> 2018-05-10 10:34 GMT-03:00 Chris Angelico :
>>  A "!j" flag
>> could take an iterable, format each element using the given format,
>> and then join them. The letter "j" makes good sense then, as it
>
> Where would you indicate the separator if we use the bang notation?

It's your proposal, you can decide what works best for you. :) I don't
think there's anything quite like this, so go ahead and pick whatever
you reckon makes the most sense.

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] Inline assignments using "given" clauses

2018-05-10 Thread Alexander Belopolsky
On Thu, May 10, 2018 at 9:44 AM, Guido van Rossum  wrote:
> I'm sorry, but unless there's a sudden landslide of support for 'given' in
> favor of ':=', I'm really not going to consider it.

How much support was there for ":="?  Are you serious about bringing
back Pascal and Algol from their comfortable resting places?
___
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] PEP 572: about the operator precedence of :=

2018-05-10 Thread Paul Moore
On 10 May 2018 at 17:38, Ethan Furman  wrote:
> On 05/10/2018 09:29 AM, M.-A. Lemburg wrote:
>>
>> On 10.05.2018 15:57, Guido van Rossum wrote:
>>>
>>> On Thu, May 10, 2018 at 5:04 AM, M.-A. Lemburg wrote:
>
>
 To a (former Pascal) programmer, a := 1 doesn't read like an
 operator. It's an assignment expression. If embedded expressions
 is where Python is heading, it should be made very clear where
 the embedded expression starts and where it ends on a line.

>>>
>>> The rules we've arrived at are about as straightforward as it gets: the
>>> RHS
>>> of `:=` ends at the nearest comma or close parenthesis/bracket/brace.
>>
>>
>> That may be easy for a computer to parse, but it's not for
>> a programmer. It would be better to contain such expressions
>> inside a safe container which is clearly visible to a human
>> eye.
>>
>> ohoh = a := (1, 2, 3), 4, a * 2
>
>
> I have no problem reading that.
>
>> vs.
>>
>> aha  = ((a := (1, 2, 3)), 4, a * 2)
>
>
> The extra parens are unneeded line noise (at least for me).

I found the version with extra parens *harder* to read. Although I
will admit neither is particularly easy to read (not surprising as
it's an artificial example intended to prove a point, not a real world
use case) and in practice I'd write

a = 1, 2, 3
ohoh = a, 4, a * 2

Look ma, no parens!

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] A comprehension scope issue in PEP 572

2018-05-10 Thread Nick Coghlan
On 10 May 2018 at 23:22, Guido van Rossum  wrote:

> On Thu, May 10, 2018 at 5:17 AM, Nick Coghlan  wrote:
>
>> How would you expect this to work in cases where the generator expression
>> isn't immediately consumed? If "p" is nonlocal (or global) by default, then
>> that opens up the opportunity for it to be rebound between generator steps.
>> That gets especially confusing if you have multiple generator expressions
>> in the same scope iterating in parallel using the same binding target:
>>
>> # This is fine
>> gen1 = (p for p in range(10))
>> gen2 = (p for p in gen1)
>> print(list(gen2))
>>
>> # This is not (given the "let's reintroduce leaking from
>> comprehensions" proposal)
>> p = 0
>> gen1 = (p := q for q in range(10))
>> gen2 = (p, p := q for q in gen1)
>> print(list(gen2))
>>
>
> That's just one of several "don't do that" situations. *What will happen*
> is perhaps hard to see at a glance, but it's perfectly well specified. Not
> all legal code does something useful though, and in this case the obvious
> advice should be to use different variables.
>

I can use that *exact same argument* to justify the Python 2 comprehension
variable leaking behaviour. We decided that was a bad idea based on ~18
years of experience with it, and there hasn't been a clear justification
presented for going back on that decision presented beyond "Tim would like
using it sometimes".

PEP 572 was on a nice trajectory towards semantic simplification (removing
sublocal scoping, restricting to name targets only, prohibiting name
binding expressions in the outermost iterable of comprehensions to avoid
exposing the existing scoping quirks any more than they already are), and
then we suddenly had this bizarre turn into "and they're going to be
implicitly nonlocal or global when used in comprehension scope".


>  It also reintroduces the original problem that comprehension scopes
> solved, just in a slightly different form:
>
> # This is fine
>> for x in range(10):
>> for y in range(10):
>> transposed_related_coords = [y, x for x, y in
>> related_coords(x, y)]
>>
>> # This is not (given the "let's reintroduce leaking from
>> comprehensions" proposal)
>> for x in range(10):
>> for y in range(10):
>> related_interesting_coords = [x, y for x in
>> related_x_coord(x, y) if is_interesting(y := f(x))]
>>
>> Deliberately reintroducing stateful side effects into a nominally
>> functional construct seems like a recipe for significant confusion, even if
>> there are some cases where it might arguably be useful to folks that don't
>> want to write a named function that returns multiple values instead.
>>
>
> You should really read Tim's initial post in this thread, where he
> explains his motivation.
>

I did, and then I talked him out of it by pointing out how confusing it
would be to have the binding semantics of "x := y" be context dependent.


> It sounds like you're not buying it, but your example is just a case where
> the user is shooting themselves in the foot by reusing variable names. When
> writing `:=` you should always keep the scope of the variable in mind --
> it's no different when using `:=` outside a comprehension.
>

It *is* different, because ":=" normally binds the same as any other name
binding operation including "for x in y:" (i.e. it creates a local
variable), while at comprehension scope, the proposal has now become for "x
:= y" to create a local variable in the containing scope, while "for x in
y" doesn't. Comprehension scoping is already hard to explain when its just
a regular nested function that accepts a single argument, so I'm not
looking forward to having to explain that "x := y" implies "nonlocal x" at
comprehension scope (except that unlike a regular nonlocal declaration, it
also implicitly makes it a local in the immediately surrounding scope).

It isn't reasonable to wave this away as "It's only confusing to Nick
because he's intimately familiar with how comprehensions are implemented",
as I also wrote some of the language reference docs for the current
(already complicated) comprehension scoping semantics, and I can't figure
out how we're going to document the proposed semantics in a way that will
actually be reasonably easy for readers to follow.

The best I've been able to come up with is:

- for comprehensions at function scope (including in a lambda expression
inside a comprehension scope), a binding expression targets the nearest
function scope, not the comprehension scope, or any intervening
comprehension scope. It will appear in locals() the same way nonlocal
references usually do.
- for comprehensions at module scope, a binding expression targets the
global scope, not the comprehension scope, or any intervening comprehension
scope. It will not appear in locals() (as with any other global reference).
- for comprehensions at class scope, the class scope is ignored 

Re: [Python-ideas] PEP 572: about the operator precedence of :=

2018-05-10 Thread Ethan Furman

On 05/10/2018 09:29 AM, M.-A. Lemburg wrote:

On 10.05.2018 15:57, Guido van Rossum wrote:

On Thu, May 10, 2018 at 5:04 AM, M.-A. Lemburg wrote:



To a (former Pascal) programmer, a := 1 doesn't read like an
operator. It's an assignment expression. If embedded expressions
is where Python is heading, it should be made very clear where
the embedded expression starts and where it ends on a line.



The rules we've arrived at are about as straightforward as it gets: the RHS
of `:=` ends at the nearest comma or close parenthesis/bracket/brace.


That may be easy for a computer to parse, but it's not for
a programmer. It would be better to contain such expressions
inside a safe container which is clearly visible to a human
eye.

ohoh = a := (1, 2, 3), 4, a * 2


I have no problem reading that.


vs.

aha  = ((a := (1, 2, 3)), 4, a * 2)


The extra parens are unneeded line noise (at least for me).

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


Re: [Python-ideas] PEP 572: about the operator precedence of :=

2018-05-10 Thread M.-A. Lemburg
On 10.05.2018 15:57, Guido van Rossum wrote:
> On Thu, May 10, 2018 at 5:04 AM, M.-A. Lemburg  wrote:
> 
>> To a (former Pascal) programmer, a := 1 doesn't read like an
>> operator. It's an assignment expression. If embedded expressions
>> is where Python is heading, it should be made very clear where
>> the embedded expression starts and where it ends on a line.
>>
> 
> The rules we've arrived at are about as straightforward as it gets: the RHS
> of `:=` ends at the nearest comma or close parenthesis/bracket/brace.

That may be easy for a computer to parse, but it's not for
a programmer. It would be better to contain such expressions
inside a safe container which is clearly visible to a human
eye.

ohoh = a := (1, 2, 3), 4, a * 2

vs.

aha  = ((a := (1, 2, 3)), 4, a * 2)

You'd simplify the above logic to: the RHS of ":=" ends at the
nearest closing parenthesis.

> OT about the name: despite Tim's relentless pushing of "binding
> expressions" in the end I think they should be called "assignment
> expressions" just like in C.

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Experts (#1, May 10 2018)
>>> Python Projects, Coaching and Consulting ...  http://www.egenix.com/
>>> Python Database Interfaces ...   http://products.egenix.com/
>>> Plone/Zope Database Interfaces ...   http://zope.egenix.com/


::: We implement business ideas - efficiently in both time and costs :::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
   Registered at Amtsgericht Duesseldorf: HRB 46611
   http://www.egenix.com/company/contact/
  http://www.malemburg.com/

___
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] Have a "j" format option for lists

2018-05-10 Thread Facundo Batista
2018-05-10 10:34 GMT-03:00 Chris Angelico :

>>
>> Ideally, it will handle *any* iterable.
>
> If it's to handle arbitrary iterables, it can't be the normal style of
> "take this string, pass it to the object's __format__ method, and let
> it interpret it". That's why I suggested a bang notation instead. We
> have some already:

Yes, I think it fits better, as it's not just a formatting, it's more
an "operation"...

>  A "!j" flag
> could take an iterable, format each element using the given format,
> and then join them. The letter "j" makes good sense then, as it

Where would you indicate the separator if we use the bang notation?

Thanks!

-- 
.Facundo

Blog: http://www.taniquetil.com.ar/plog/
PyAr: http://www.python.org/ar/
Twitter: @facundobatista
___
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] Inline assignments using "given" clauses

2018-05-10 Thread Gustavo Carneiro
On Thu, 10 May 2018 at 16:49, Ed Kellett  wrote:

> On 2018-05-10 16:10, Guido van Rossum wrote:
> > Please no, it's not that easy. I can easily generate a stream of +1s or
> -1s
> > for any proposal. I'd need well-reasoned explanations and it would have
> to
> > come from people who are willing to spend significant time writing it up
> > eloquently. Nick has tried his best and failed to convince me. So the bar
> > is high.
> >
> > (Also note that most of the examples that have been brought up lately
> were
> > meant to illustrate the behavior in esoteric corner cases while I was
> > working out the fine details of the semantics. Users should use this
> > feature sparingly and stay very far away of those corner cases -- but
> they
> > have to be specified in order to be able to implement this thing.)
>
> Poor prospects, then, but I'll do my best.
>
> I think the most obvious argument (to me) favouring `given` over `:=` is
> that it separates the two things it's doing:
>
> if m.group(2) given m = pattern.search(data):
>
> as opposed to the more-nested := version:
>
> if (m := pattern.search(data)).group(2):
>
> which, at least to me, is more complicated to think about because it
> feels like it's making the .group() something to do with the assignment.
>
> Put another way, I think your use of parentheses when discussing the
> *pronunciation* of this thing is telling. It feels as though one needs
> to start in the middle and then go in both directions at once, first
> explaining the origin (or destination) of the operand in question in a
> parenthesized offshoot, and then switching context and describing what
> is done to it. It's midly mentally taxing. I'm sure we can all live with
> that, but I don't want to: Python's exceptionally-readable syntax is one
> of the bigger reasons I choose it.
>
> There's a striking parallel in C, where the well-known idiom:
>
> while ((c = getchar()) != EOF) ...
>
> has an obviously-nicer alternative:
>
> while (c = getchar(), c != EOF) ...
>
> Most people I show this to agree that it's nicer, despite the fact that
> it manages to repeat a variable name *and* use the comma operator. I
> don't have proof, but I'd suggest that unwrapping that layer of context
> for the reader imparts a significant benefit.
>
> The C example also provides a convenient test: if you think the former
> example is nicer, I can just give up now ;)
>

IMHO, all these toy examples don't translate well to the real world because
they tend to use very short variable names while in real world [good
written code] tends to select longer more descriptive variable names.

Try replacing "c" with  a longer name, like input_command, then it becomes:

while ((input_command = getchar()) != EOF) ...

while (input_command = getchar(), input_command != EOF) ...

In the second example, having to type the variable name twice is an
annoyance that adds almost nothing to readability, so I would definitely
prefer the first one.

The "given" proposals have the same issue.

(a shame we can't use "as", for reasons already stated, it would have been
perfect otherwise)

-- 
Gustavo J. A. M. Carneiro
Gambit Research
"The universe is always one step beyond logic." -- Frank Herbert
___
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] Inline assignments using "given" clauses

2018-05-10 Thread Ed Kellett
On 2018-05-10 16:10, Guido van Rossum wrote:
> Please no, it's not that easy. I can easily generate a stream of +1s or -1s
> for any proposal. I'd need well-reasoned explanations and it would have to
> come from people who are willing to spend significant time writing it up
> eloquently. Nick has tried his best and failed to convince me. So the bar
> is high.
> 
> (Also note that most of the examples that have been brought up lately were
> meant to illustrate the behavior in esoteric corner cases while I was
> working out the fine details of the semantics. Users should use this
> feature sparingly and stay very far away of those corner cases -- but they
> have to be specified in order to be able to implement this thing.)

Poor prospects, then, but I'll do my best.

I think the most obvious argument (to me) favouring `given` over `:=` is
that it separates the two things it's doing:

if m.group(2) given m = pattern.search(data):

as opposed to the more-nested := version:

if (m := pattern.search(data)).group(2):

which, at least to me, is more complicated to think about because it
feels like it's making the .group() something to do with the assignment.

Put another way, I think your use of parentheses when discussing the
*pronunciation* of this thing is telling. It feels as though one needs
to start in the middle and then go in both directions at once, first
explaining the origin (or destination) of the operand in question in a
parenthesized offshoot, and then switching context and describing what
is done to it. It's midly mentally taxing. I'm sure we can all live with
that, but I don't want to: Python's exceptionally-readable syntax is one
of the bigger reasons I choose it.

There's a striking parallel in C, where the well-known idiom:

while ((c = getchar()) != EOF) ...

has an obviously-nicer alternative:

while (c = getchar(), c != EOF) ...

Most people I show this to agree that it's nicer, despite the fact that
it manages to repeat a variable name *and* use the comma operator. I
don't have proof, but I'd suggest that unwrapping that layer of context
for the reader imparts a significant benefit.

The C example also provides a convenient test: if you think the former
example is nicer, I can just give up now ;)



signature.asc
Description: OpenPGP digital signature
___
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] Inline assignments using "given" clauses

2018-05-10 Thread Guido van Rossum
Please no, it's not that easy. I can easily generate a stream of +1s or -1s
for any proposal. I'd need well-reasoned explanations and it would have to
come from people who are willing to spend significant time writing it up
eloquently. Nick has tried his best and failed to convince me. So the bar
is high.

(Also note that most of the examples that have been brought up lately were
meant to illustrate the behavior in esoteric corner cases while I was
working out the fine details of the semantics. Users should use this
feature sparingly and stay very far away of those corner cases -- but they
have to be specified in order to be able to implement this thing.)

On Thu, May 10, 2018 at 10:26 AM, marky1991 .  wrote:

> If it just needs a stream of +1s, I personally like the "given" approach
> much more than the ":=" approach, for all of the many reasons repeated many
> times in the various email chains. (I preferred it as "as", but that's been
> struck down already) (and if it's between ":=" and not having them at all,
> I would rather just not have them)
>
>


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


Re: [Python-ideas] Inline assignments using "given" clauses

2018-05-10 Thread marky1991 .
If it just needs a stream of +1s, I personally like the "given" approach
much more than the ":=" approach, for all of the many reasons repeated many
times in the various email chains. (I preferred it as "as", but that's been
struck down already) (and if it's between ":=" and not having them at all,
I would rather just not have them)
___
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] Inline assignments using "given" clauses

2018-05-10 Thread Rhodri James

On 10/05/18 14:44, Guido van Rossum wrote:

I'm sorry, but unless there's a sudden landslide of support for 'given' in
favor of ':=', I'm really not going to consider it.


OK, this is my ha'p'th in favour of 'given', for what little it's worth. 
 The more I see of general assignment expressions, the less I like 
them.  All I really want is a less clumsy way to write


while true:
thing_to_do = get_something_to_do()
if thing_to_do == GET_OUT_OF_HERE:
break
# else do stuff

--
Rhodri James *-* Kynesim Ltd
___
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] PEP 572: about the operator precedence of :=

2018-05-10 Thread Guido van Rossum
On Thu, May 10, 2018 at 5:04 AM, M.-A. Lemburg  wrote:

> To a (former Pascal) programmer, a := 1 doesn't read like an
> operator. It's an assignment expression. If embedded expressions
> is where Python is heading, it should be made very clear where
> the embedded expression starts and where it ends on a line.
>

The rules we've arrived at are about as straightforward as it gets: the RHS
of `:=` ends at the nearest comma or close parenthesis/bracket/brace.

OT about the name: despite Tim's relentless pushing of "binding
expressions" in the end I think they should be called "assignment
expressions" just like in C.

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


Re: [Python-ideas] PEP 572: about the operator precedence of :=

2018-05-10 Thread Guido van Rossum
On Thu, May 10, 2018 at 3:32 AM, Terry Reedy  wrote:

> On 5/9/2018 11:33 PM, Guido van Rossum wrote:
>
> I now think that the best way out is to rule `:=` in the top level
>> expression of an expression statement completely
>>
>
> I would like to be able to interactively enter
>
> >>> a: = f(2,4)
>
> to have 'a' echoed as well as bound.
>

I hope that's a typo (the can be no space between `:` and `=`, since `:=`
is a single token, just like `<=').

We *could* make this work while still ruling out the ambiguous cases (which
involve top-level commas on either side of the assignment expression).

OTOH I worry that this particular feature would cause `:=` to become part
of many a teacher's bag of tricks to show off, exposing users to it way too
early for any curriculum, and it might then elicit complaints that

>>> def f():
... a := 5
...
>>> f()
>>>

doesn't print `5`.

So all in all I'm not sure I think this is important enough to support, and
the rule "Use `:=` in expressions, not as a top level assignment" seems
easier to explain and understand.

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


Re: [Python-ideas] Inline assignments using "given" clauses

2018-05-10 Thread Guido van Rossum
I'm sorry, but unless there's a sudden landslide of support for 'given' in
favor of ':=', I'm really not going to consider it.

I'd pronounce "if (x := y) > 0" as either "if y (assigned to x) is greater
than zero" or "if x (assigned from y) is greater than zero".

On Thu, May 10, 2018 at 6:39 AM, Nick Coghlan  wrote:

> On 8 May 2018 at 04:19, Brett Cannon  wrote:
>
>> My brain wants to drop the variable name in front of 'given':
>>
>> if given m = pattern.search(data):
>>
>> while given m = pattern.search(remaining_data):
>>
>> Maybe it's because the examples use such a short variable name?
>>
>
> Does that change if the condition isn't just "bool(name)"? For example:
>
> if y > 0 given y = f(x):
> ...
>
> That's the situation where I strongly prefer the postfix operator
> spelling, since it's pretty clear how I should pronounce it (i.e. "if y is
> greater than zero, given y is set to f-of-x, then ..."). By contrast, while
> a variety of  plausible suggestions have been made, I still don't really
> know how to pronounce "if (y := f(x)) > 0:)" in a way that's going to be
> clear to an English-speaking listener (aside from pronouncing it the same
> way as I'd pronounce the version using "given", but that then raises the
> question of "Why isn't it written the way it is pronounced?").
>
> I do agree with Tim that the name repetition would strongly encourage the
> use of short names rather than long ones (since you're always typing them
> at least twice), such that we'd probably see code like:
>
> while not probable_prime(n) given (n =
> highbit | randrange(1, highbit, 2)):
> pass
>
> Rather than the more explicit:
>
> while not probable_prime(candidate) given (candidate =
> highbit | randrange(1, highbit, 2)):
> pass
>
> However, I'd still consider both of those easier to follow than:
>
> while not probable_prime(candidate := highbit | randrange(1, highbit,
> 2)):
> pass
>
> since it's really unclear to me that "candidate" in the latter form is a
> positional argument being bound to a name in the local environment, and
> *not* a keyword argument being passed to "probable_prime".
>
> I've also been pondering what the given variant might look like as a
> generally available postfix operator, rather than being restricted to
> if/elif/while clauses, and I think that would have interesting implications
> for the flexibility of its usage in comprehensions, since there would now
> be *three* places where "given" could appear (as is already the case for
> the inline binding operator spelling):
>
> - in the result expression
> - in the iterable expression
> - in the filter expression
>
> That is:
>
> [(x, y, x - y) given y = f(x) for x in data]
> [(x, data) for x in data given data = get_data()]
> [(x, y, x/y) for x in data if y given y = f(x)]
>
> Rather than:
>
> [(x, y := f(x), x - y) for x in data]
> [(x, data) for x in data := get_data()]
> [(x, y, x/y) for x in data if y := f(x)]
>
> Opening it up that way would allow for some odd usages that might need to
> be discouraged in PEP 8 (like explicitly preferring "probable_prime(n)
> given n = highbit | randrange(1, highbit, 2)" to "probable_prime(n given n
> = highbit | randrange(1, highbit, 2))"), but it would probably still be
> simpler overall than attempting to restrict the construct purely to
> if/elif/while.
>
> Even as a generally available postfix keyword, "given" should still be
> amenable to the treatment where it could be allowed as a variable name in a
> non-operator context (since we don't allow two adjacent expressions to
> imply a function call, it's only prefix keywords that have to be disallowed
> as names to avoid ambiguity in the parser).
>
> 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/
>
>


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


Re: [Python-ideas] Have a "j" format option for lists

2018-05-10 Thread Chris Angelico
On Thu, May 10, 2018 at 11:13 PM, Facundo Batista
 wrote:
>> I would like to see you flesh out the idea. In particular, I'd like to see 
>> you
>> address cases where:
>> 1. The underlying members in the collection are not strings. Besides the 
>> basic
>>types such as numbers, it would also be nice to be able to apply formats
>>recursively so that one can construct a string using the attributes of
>>members that are objects or items or other collections.
>
> I didn't think about this at the time. I have the feeling (not really
> well thought yet) that "recursive formatting" will complicate
> everything too much, that doing str() (as {} defaults to) on every
> object would fulfill most of the basic cases and keep this simple.
>
>
>> 2. The ability to handle collections other than simple lists or iterables, 
>> such
>>as dictionaries.
>
> Ideally, it will handle *any* iterable.

If it's to handle arbitrary iterables, it can't be the normal style of
"take this string, pass it to the object's __format__ method, and let
it interpret it". That's why I suggested a bang notation instead. We
have some already:

>>> x = "O'Really?"
>>> print(f"!s: {x!s}  !r: {x!r}")
!s: O'Really?  !r: "O'Really?"

Those markers apply to ANY object, and pass it through str() or repr()
respectively, before using any provided format string. A "!j" flag
could take an iterable, format each element using the given format,
and then join them. The letter "j" makes good sense then, as it
parallels str.join() - this would be broadly similar to
"...".join(format(...) for x in iter).

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] A comprehension scope issue in PEP 572

2018-05-10 Thread Guido van Rossum
On Thu, May 10, 2018 at 5:17 AM, Nick Coghlan  wrote:

> On 9 May 2018 at 03:06, Guido van Rossum  wrote:
>
>> So the way I envision it is that *in the absence of a nonlocal or global
>> declaration in the containing scope*, := inside a comprehension or genexpr
>> causes the compiler to assign to a local in the containing scope, which is
>> elevated to a cell (if it isn't already). If there is an explicit nonlocal
>> or global declaration in the containing scope, that is honored.
>>
>> Examples:
>>
>>   # Simplest case, neither nonlocal nor global declaration
>>   def foo():
>>   [p := q for q in range(10)]  # Creates foo-local variable p
>>   print(p)  # Prints 9
>>
>>   # There's a nonlocal declaration
>>   def bar():
>>   p = 42  # Needed to determine its scope
>>   def inner():
>>   nonlocal p
>>   [p := q for q in range(10)]  # Assigns to p in bar's scope
>>   inner()
>>   print(p)  # Prints 9
>>
>>   # There's a global declaration
>>   def baz():
>>   global p
>>   [p := q for q in range(10)]
>>   baz()
>>   print(p)  # Prints 9
>>
>> All these would work the same way if you wrote list(p := q for q in
>> range(10)) instead of the comprehension.
>>
>
> How would you expect this to work in cases where the generator expression
> isn't immediately consumed? If "p" is nonlocal (or global) by default, then
> that opens up the opportunity for it to be rebound between generator steps.
> That gets especially confusing if you have multiple generator expressions
> in the same scope iterating in parallel using the same binding target:
>
> # This is fine
> gen1 = (p for p in range(10))
> gen2 = (p for p in gen1)
> print(list(gen2))
>
> # This is not (given the "let's reintroduce leaking from
> comprehensions" proposal)
> p = 0
> gen1 = (p := q for q in range(10))
> gen2 = (p, p := q for q in gen1)
> print(list(gen2))
>

That's just one of several "don't do that" situations. *What will happen*
is perhaps hard to see at a glance, but it's perfectly well specified. Not
all legal code does something useful though, and in this case the obvious
advice should be to use different variables.


> It also reintroduces the original problem that comprehension scopes
> solved, just in a slightly different form:
>
> # This is fine
> for x in range(10):
> for y in range(10):
> transposed_related_coords = [y, x for x, y in
> related_coords(x, y)]
>
> # This is not (given the "let's reintroduce leaking from
> comprehensions" proposal)
> for x in range(10):
> for y in range(10):
> related_interesting_coords = [x, y for x in related_x_coord(x,
> y) if is_interesting(y := f(x))]
>
> Deliberately reintroducing stateful side effects into a nominally
> functional construct seems like a recipe for significant confusion, even if
> there are some cases where it might arguably be useful to folks that don't
> want to write a named function that returns multiple values instead.
>

You should really read Tim's initial post in this thread, where he explains
his motivation. It sounds like you're not buying it, but your example is
just a case where the user is shooting themselves in the foot by reusing
variable names. When writing `:=` you should always keep the scope of the
variable in mind -- it's no different when using `:=` outside a
comprehension.

PS. Thanks for the suggestion about conflicting signals about scope; that's
what we'll do.

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


Re: [Python-ideas] Have a "j" format option for lists

2018-05-10 Thread Facundo Batista
2018-05-10 8:02 GMT-03:00 Rhodri James :
> On 09/05/18 20:56, Facundo Batista wrote:
>>
>> 2018-05-09 13:48 GMT-03:00 Rhodri James :
>>
>>> -1 until you give me an actual spec rather than a curious example.
>>>
>>> Sorry if that sounds a bit rude, but I spend most of my time trying to
>>> find
>>
>>
>> Be sorry, it was rude.
>
>
> On reflection, I'm not sorry at all.  It needed to be said, and attempting
> to deduce a spec from a single example has already caused people to go off
> in a variety of different directions.  If provoking you into being even a
> bit more specific gets our collective cat herd moving in something more like
> the same direction, it'll be worth it.

I apologize if *I* was rude or made feel you badly in any way.


> I too didn't equate "j" with "join".  I was somewhat expecting "l" for
> "list" given that "s" for "sequence" is taken.  Should I take it that
> everything from the colon to the "j" is an implicitly delimited string to
> use for joining?

Yes.


> If so, does anything in that string need escaping, like say braces or other
> "j"s?  I'm not sure if format specifiers currently allow arbitrary text (I
> don't think they do, but I'm not sure), which might make this a more serious
> undertaking than it first looks.  Alternatively, are certain characters
> forbidden in this implicit join string?

Don't know.

I think I need to read this for ideas:
https://mail.python.org/pipermail/python-ideas/2015-September/035789.html


> I presume also that no other formatting is possible with this specifier: no
> field widths, no justification, none of the other stuff applicable to
> strings.  I'm not talking about formatting the original strings (or
> whatever) in the list, that would clearly involve crazy amounts of
> sub-formatting and look like a complete mess in the code, but I can see a
> need for formatting the final joined string, and I can't see a way of doing
> that from what you've given us.

I concur, joining *and* do special formatting for the elements would
be a mess. That's way in other mail I said that probably cover the
basic case (doing just str()) is better; if you want something more
complex you always can do it as a separate step :/

-- 
.Facundo

Blog: http://www.taniquetil.com.ar/plog/
PyAr: http://www.python.org/ar/
Twitter: @facundobatista
___
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] Have a "j" format option for lists

2018-05-10 Thread Facundo Batista
> I would like to see you flesh out the idea. In particular, I'd like to see you
> address cases where:
> 1. The underlying members in the collection are not strings. Besides the basic
>types such as numbers, it would also be nice to be able to apply formats
>recursively so that one can construct a string using the attributes of
>members that are objects or items or other collections.

I didn't think about this at the time. I have the feeling (not really
well thought yet) that "recursive formatting" will complicate
everything too much, that doing str() (as {} defaults to) on every
object would fulfill most of the basic cases and keep this simple.


> 2. The ability to handle collections other than simple lists or iterables, 
> such
>as dictionaries.

Ideally, it will handle *any* iterable.

Thanks!

-- 
.Facundo

Blog: http://www.taniquetil.com.ar/plog/
PyAr: http://www.python.org/ar/
Twitter: @facundobatista
___
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] Have a "j" format option for lists

2018-05-10 Thread Facundo Batista
2018-05-09 21:45 GMT-03:00 Steven D'Aprano :
> On Wed, May 09, 2018 at 04:56:38PM -0300, Facundo Batista wrote:
>> 2018-05-09 13:48 GMT-03:00 Rhodri James :
>>
>> > -1 until you give me an actual spec rather than a curious example.
>> >
>> > Sorry if that sounds a bit rude, but I spend most of my time trying to find
>>
>> Be sorry, it was rude.
>
> I do not agree that Rhodri's comments were rude. They were frank and
> honest constructive criticism of the presentation of your idea.
>
> I have no patience with hair-trigger accusations of "rudeness" as a
> debating tactic to curtail criticism, and your response to Rhodri's mild
> and fair words looks exactly like that. Whether you intended it that way
> or not, that is what it looks like to me.

I totally apologize if I made you, Rhodri or anybody to feel bad about
this. It was not my intention to do that.

It felt rude to me and I reacted badly, and too fast. I should have
behaved differently, sorry again.

Regards,

-- 
.Facundo

Blog: http://www.taniquetil.com.ar/plog/
PyAr: http://www.python.org/ar/
Twitter: @facundobatista
___
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] A comprehension scope issue in PEP 572

2018-05-10 Thread Nick Coghlan
On 9 May 2018 at 03:06, Guido van Rossum  wrote:

> So the way I envision it is that *in the absence of a nonlocal or global
> declaration in the containing scope*, := inside a comprehension or genexpr
> causes the compiler to assign to a local in the containing scope, which is
> elevated to a cell (if it isn't already). If there is an explicit nonlocal
> or global declaration in the containing scope, that is honored.
>
> Examples:
>
>   # Simplest case, neither nonlocal nor global declaration
>   def foo():
>   [p := q for q in range(10)]  # Creates foo-local variable p
>   print(p)  # Prints 9
>
>   # There's a nonlocal declaration
>   def bar():
>   p = 42  # Needed to determine its scope
>   def inner():
>   nonlocal p
>   [p := q for q in range(10)]  # Assigns to p in bar's scope
>   inner()
>   print(p)  # Prints 9
>
>   # There's a global declaration
>   def baz():
>   global p
>   [p := q for q in range(10)]
>   baz()
>   print(p)  # Prints 9
>
> All these would work the same way if you wrote list(p := q for q in
> range(10)) instead of the comprehension.
>

How would you expect this to work in cases where the generator expression
isn't immediately consumed? If "p" is nonlocal (or global) by default, then
that opens up the opportunity for it to be rebound between generator steps.
That gets especially confusing if you have multiple generator expressions
in the same scope iterating in parallel using the same binding target:

# This is fine
gen1 = (p for p in range(10))
gen2 = (p for p in gen1)
print(list(gen2))

# This is not (given the "let's reintroduce leaking from
comprehensions" proposal)
p = 0
gen1 = (p := q for q in range(10))
gen2 = (p, p := q for q in gen1)
print(list(gen2))

It also reintroduces the original problem that comprehension scopes solved,
just in a slightly different form:

# This is fine
for x in range(10):
for y in range(10):
transposed_related_coords = [y, x for x, y in related_coords(x,
y)]

# This is not (given the "let's reintroduce leaking from
comprehensions" proposal)
for x in range(10):
for y in range(10):
related_interesting_coords = [x, y for x in related_x_coord(x,
y) if is_interesting(y := f(x))]

Deliberately reintroducing stateful side effects into a nominally
functional construct seems like a recipe for significant confusion, even if
there are some cases where it might arguably be useful to folks that don't
want to write a named function that returns multiple values instead.

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] Have a "j" format option for lists

2018-05-10 Thread Eric V. Smith

On 5/10/18 7:02 AM, Rhodri James wrote:

If so, does anything in that string need escaping, like say braces or
other "j"s?  I'm not sure if format specifiers currently allow arbitrary
text (I don't think they do, but I'm not sure), which might make this a
more serious undertaking than it first looks.  Alternatively, are
certain characters forbidden in this implicit join string?


A format spec can contain anything. Its interpretation is completely 
left to the type being formatted. For example, a datetime supports a 
strftime() string, which can be anything:


>>> '{:today is %Y-%m-%d}'.format(datetime.datetime.now())
'today is 2018-05-10'

In str.format(), there's a restriction that the format spec can't 
contain a closing brace }, but that's solely a restriction of the string 
scanning that's going on, and not a function of the __format__ protocol 
itself. For example:


>>> format(datetime.datetime.now(), 'today is %Y-%m-%d {tada!}')
'today is 2018-05-10 {tada!}'

I always suggest to people that they don't look at f-strings or 
str.format() when coming up with examples, but instead use format() or 
obj.__format__() to more clearly see what's happening. In Facundo's 
original example:


authors = ["John", "Mary", "Estela"]
"Authors: {:, j}".format(authors)

it's best to think of this as:

"Authors: " + format(authors, ', j')

or the equivalent (in this case):

"Authors: " + authors.__format__(', j')

authors is a list in this example, so list.__format__() would have to 
understand the format spec ', j'. Okay, that's probably doable (although 
I'm not advocating it!). But you really don't want this to work just for 
lists. What about:


def authors1():
   yield "John"
   yield "Mary"
   yield "Estela"
format(authors1(), ', j')

How would that work? Would generators grow a __format__()? It's not 
possible to add this functionality to every iterator past, present, and 
future.


This is why I think a wrapper that adds a __format__(), which itself 
calls str.join(), is the only way to handle this. This is what I showed 
in my earlier response as the Join class. And at that point, I don't 
think it's really worth the hassle over just calling str.join().


Eric
___
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] Runtime assertion with no overhead when not active

2018-05-10 Thread Steven D'Aprano
On Thu, May 10, 2018 at 08:55:44AM +0100, Barry Scott wrote:

> This idea requires the same sort of machinery in python that I was 
> hoping for to implement the short circuit logging.

I'm working on an idea for delayed evaluation of expressions, and I 
think your idea of logging below would make an excellent use-case.

> My logging example would be
> 
>   log( control_flag, msg_expr )
> 
> expanding to:
> 
>   if :
>   log_function(  )

The idea isn't yet ready for Python-Ideas, but if you're interested feel 
free to contact me off-list.


-- 
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] PEP 572: about the operator precedence of :=

2018-05-10 Thread Nick Coghlan
On 10 May 2018 at 13:33, Guido van Rossum  wrote:

> (I vaguely recall this has been brought up before, but I'm too lazy to
> find the subtread. So it goes.)
>
> PEP 572 currently seems to specify that when used in expressions, the
> precedence of `:=` is lower (i.e. it binds more tightly) than all operators
> except for the comma. I derive this from the single example `stuff = [[y :=
> f(x), x/y] for x in range(5)]`.
>
> From this it would follow that `f(a := 1, a)` is equivalent to `a = 1;
> f(1, 1)`, and also that `(a := 1, a)` is equivalent to `a = 1; (1, 1)`.
> (Although M.A.L. objected to this.)
>
> But what should `a := 1, 1` at the top level (as a statement) do? On the
> one hand, analogy with the above suggest that it is equivalent to `a = 1;
> (1, 1)`. But on the other hand, it would be really strange if the following
> two lines had different meanings:
>
> a = 1, 1   # a = (1, 1)
> a := 1, 1  # a = 1; (1, 1)
>
> I now think that the best way out is to rule `:=` in the top level
> expression of an expression statement completely (it would still be okay
> inside parentheses, where it would bind tighter than comma).
>

FWIW, this is one of the ambiguities that the generalised postfix
expression form of the given clause would reduce fairly significantly by
separating the result expression from the bound expression:

a = 1, 1
a given a = 1, 1 # As above, but also returns a
a = 1, x, 3 given x = 2

They also compose fairly nicely as an essentially right associative
operator:

a given a = 1, x, 3 given x = 2
a given a = (1, x, 3 given x = 2) # Same as previous
(a given a = 1), x, 3 given x = 2 # Forcing left-associativity

While you do have to repeat the bound name at least once, you gain a much
clearer order of execution (while it's an order of execution that's
right-to-left rather than left-to-right, "rightmost expression first" is
the normal way assignments get evaluated anyway).

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] Runtime assertion with no overhead when not active

2018-05-10 Thread Nick Coghlan
On 10 May 2018 at 17:55, Barry Scott  wrote:

> On 7 May 2018, at 18:52, Guido van Rossum  wrote:
>
> On Mon, May 7, 2018 at 6:24 AM, Serhiy Storchaka 
> wrote:
>
>> I just don't understand why you need a new keyword for writing runtime
>> checks.
>>
>
> Oh, that's pretty clear. The OP wants to be able to turn these checks off
> with some flag he can set/clear at runtime, and when it's off he doesn't
> want to incur the overhead of evaluating the check. The assert statement
> has the latter property, but you have to use -O to turn it off. He
> basically wants a macro so that
>
>   runtime_assert()
>
> expands to
>
>   if  and ():
>   raise AssertionError
>
> In Lisp this would be easy. :-)
>
>
> This idea requires the same sort of machinery in python that I was hoping
> for to implement the short circuit logging.
>
> My logging example would be
>
> log( control_flag, msg_expr )
>
> expanding to:
>
> if :
> log_function(  )
>

Logging is the example that came to mind for me as well -
https://docs.python.org/3/howto/logging.html#optimization discusses the
"logging.isEnabledFor" API, and how it can be used to avoid the overhead of
expensive state queries when the result log message would just be discarded
anyway.

Generally speaking though, the spelling for that kind of lazy evaluation is
to accept a zero-argument callable, which can then be used with "lambda: "
at the call site:

runtime_assert(lambda: )

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] Have a "j" format option for lists

2018-05-10 Thread Rhodri James

On 09/05/18 20:56, Facundo Batista wrote:

2018-05-09 13:48 GMT-03:00 Rhodri James :


-1 until you give me an actual spec rather than a curious example.

Sorry if that sounds a bit rude, but I spend most of my time trying to find


Be sorry, it was rude.


On reflection, I'm not sorry at all.  It needed to be said, and 
attempting to deduce a spec from a single example has already caused 
people to go off in a variety of different directions.  If provoking you 
into being even a bit more specific gets our collective cat herd moving 
in something more like the same direction, it'll be worth it.


In that spirit, and trying not to take this as a challenge to see how 
rude I can be without actually being rude: ;-)


I too didn't equate "j" with "join".  I was somewhat expecting "l" for 
"list" given that "s" for "sequence" is taken.  Should I take it that 
everything from the colon to the "j" is an implicitly delimited string 
to use for joining?


If so, does anything in that string need escaping, like say braces or 
other "j"s?  I'm not sure if format specifiers currently allow arbitrary 
text (I don't think they do, but I'm not sure), which might make this a 
more serious undertaking than it first looks.  Alternatively, are 
certain characters forbidden in this implicit join string?


I presume also that no other formatting is possible with this specifier: 
no field widths, no justification, none of the other stuff applicable to 
strings.  I'm not talking about formatting the original strings (or 
whatever) in the list, that would clearly involve crazy amounts of 
sub-formatting and look like a complete mess in the code, but I can see 
a need for formatting the final joined string, and I can't see a way of 
doing that from what you've given us.


I'm not convinced, I admit.  Your use case

>>> print("{title!r} (${price}) by {authors:, j}".format(**info))
"A book" ($2.34) by John, Mary, Estela

is moderately compelling, but is starting to look too magic for my 
tastes.  I think it's the implicitly delimited join string; it isn't 
obvious at first sight that the comma and space aren't independently 
meaningful in some obscure way, like everything else in that position in 
a format would be.




This list is for throwing ideas and see if they gain momentum... if
yes, it will be time for a PEP.

I know how to do a PEP, believe me.

But if we'll be asking for a Spec for every idea we think may be
valuable, we'll stall.


Raising the barrier a bit is no bad thing in my opinion; it shouldn't be 
easy to add things to Python, otherwise we'd have a much uglier 
language.  Regardless, there is a difference between a full-blown PEP 
and an outline spec.  Much as I would like to have every jot and tittle 
in place for a first draft, I know that's not realistic and I don't 
expect it.  On the other hand, bitter experience has taught me that when 
the first draft of a proposal is as nebulous as what you gave us, I 
should walk away from the incipient disaster right now.


--
Rhodri James *-* Kynesim Ltd
___
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] PEP 572: about the operator precedence of :=

2018-05-10 Thread David Mertz
On Wed, May 9, 2018, 11:53 PM Guido van Rossum  wrote:

> Oh, I hadn't even though of combining the two in one statement. That
> example is truly horrible (on first skim I didn't even notice it used two
> different assignment operators!) and strengthens my confidence that we
> should just disallow an un-parenthesized `:=` operator at the top level,
> where now the top level includes the RHS of a classic assignment.
>

IMO, I would strongly prefer calling an unparenthesized top-level ':=' a
SyntaxError.

>
___
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] A comprehension scope issue in PEP 572

2018-05-10 Thread Nick Coghlan
On 9 May 2018 at 03:57, Tim Peters  wrote:

> These all match my expectations.  Some glosses:
>
> [Guido]
> > We should probably define what happens when you write [p := p for p in
> > range(10)]. I propose that this overwrites the loop control variable
> rather
> > than creating a second p in the containing scope -- either way it's
> probably
> > a typo anyway.
>
> A compile-time error would be fine by me too.  Creating two meanings
> for `p` is nuts - pick one in case of conflict.  I suggested before
> that the first person with a real use case for this silliness should
> get the meaning their use case needs, but nobody bit, so "it's local
> then" is fine.
>

I'd suggest that the handling of conflicting global and nonlocal
declarations provides a good precedent here:

>>> def f():
... global x
... nonlocal x
... x = 1
...
  File "", line 2
SyntaxError: name 'x' is nonlocal and global

Since using a name as a binding target *and* as the iteration variable
would effectively be declaring it as both local and nonlocal, or as local
and global.

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] Inline assignments using "given" clauses

2018-05-10 Thread Nick Coghlan
On 8 May 2018 at 04:19, Brett Cannon  wrote:

> My brain wants to drop the variable name in front of 'given':
>
> if given m = pattern.search(data):
>
> while given m = pattern.search(remaining_data):
>
> Maybe it's because the examples use such a short variable name?
>

Does that change if the condition isn't just "bool(name)"? For example:

if y > 0 given y = f(x):
...

That's the situation where I strongly prefer the postfix operator spelling,
since it's pretty clear how I should pronounce it (i.e. "if y is greater
than zero, given y is set to f-of-x, then ..."). By contrast, while a
variety of  plausible suggestions have been made, I still don't really know
how to pronounce "if (y := f(x)) > 0:)" in a way that's going to be clear
to an English-speaking listener (aside from pronouncing it the same way as
I'd pronounce the version using "given", but that then raises the question
of "Why isn't it written the way it is pronounced?").

I do agree with Tim that the name repetition would strongly encourage the
use of short names rather than long ones (since you're always typing them
at least twice), such that we'd probably see code like:

while not probable_prime(n) given (n =
highbit | randrange(1, highbit, 2)):
pass

Rather than the more explicit:

while not probable_prime(candidate) given (candidate =
highbit | randrange(1, highbit, 2)):
pass

However, I'd still consider both of those easier to follow than:

while not probable_prime(candidate := highbit | randrange(1, highbit,
2)):
pass

since it's really unclear to me that "candidate" in the latter form is a
positional argument being bound to a name in the local environment, and
*not* a keyword argument being passed to "probable_prime".

I've also been pondering what the given variant might look like as a
generally available postfix operator, rather than being restricted to
if/elif/while clauses, and I think that would have interesting implications
for the flexibility of its usage in comprehensions, since there would now
be *three* places where "given" could appear (as is already the case for
the inline binding operator spelling):

- in the result expression
- in the iterable expression
- in the filter expression

That is:

[(x, y, x - y) given y = f(x) for x in data]
[(x, data) for x in data given data = get_data()]
[(x, y, x/y) for x in data if y given y = f(x)]

Rather than:

[(x, y := f(x), x - y) for x in data]
[(x, data) for x in data := get_data()]
[(x, y, x/y) for x in data if y := f(x)]

Opening it up that way would allow for some odd usages that might need to
be discouraged in PEP 8 (like explicitly preferring "probable_prime(n)
given n = highbit | randrange(1, highbit, 2)" to "probable_prime(n given n
= highbit | randrange(1, highbit, 2))"), but it would probably still be
simpler overall than attempting to restrict the construct purely to
if/elif/while.

Even as a generally available postfix keyword, "given" should still be
amenable to the treatment where it could be allowed as a variable name in a
non-operator context (since we don't allow two adjacent expressions to
imply a function call, it's only prefix keywords that have to be disallowed
as names to avoid ambiguity in the parser).

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] PEP 572: about the operator precedence of :=

2018-05-10 Thread Chris Angelico
On Thu, May 10, 2018 at 7:04 PM, M.-A. Lemburg  wrote:
> Not sure whether this was discussed before (I'm not really
> following the discussion), but what happens if you write:
>
> check = 0 and (a := 1)
>
> ? Will "a" get assigned or not ?

No, it won't. It's the same as any other side effects after an 'and' -
that expression is completely not evaluated.

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] PEP 572: about the operator precedence of :=

2018-05-10 Thread M.-A. Lemburg
On 10.05.2018 05:52, Guido van Rossum wrote:
>> I would have := bind more tightly than the comma. Consider:
>>
>> a = 1, x := 2, 3
>>
>> IMO the only sane interpretation is "x = 2; a = 1, 2, 3". Effectively,
>> the := operator does not like to play with commas; we've already ruled
>> out "a, b := range(2)" as a means of unpacking, so it makes more sense
>> to have that simply mean "b = range(2); a, b".
>>
> 
> Oh, I hadn't even though of combining the two in one statement. That
> example is truly horrible (on first skim I didn't even notice it used two
> different assignment operators!) and strengthens my confidence that we
> should just disallow an un-parenthesized `:=` operator at the top level,
> where now the top level includes the RHS of a classic assignment.

Yes, please, and ideally not only at the top level, but
everywhere.

To a (former Pascal) programmer, a := 1 doesn't read like an
operator. It's an assignment expression. If embedded expressions
is where Python is heading, it should be made very clear where
the embedded expression starts and where it ends on a line.

Anything else will just result in hard to debug code with
subtle errors...

oops = 1, a := 2 * 3, 4, 5 - 6

By having to write:

ahhh = 1, (a := 2) * 3, 4, 5 - 6

you at least know that "(a := 2)" will evaluate to 2 in the
tuple on the right side.

Not sure whether this was discussed before (I'm not really
following the discussion), but what happens if you write:

check = 0 and (a := 1)

? Will "a" get assigned or not ?


All that said, I sometimes do wonder what people dislike
so much about explicit for-loops which make all of these
things obvious even to a complete Python newbie reading
the code.

IMO, line noise is not something Python should strive for.
Other languages such as APL are much better at that - just
look at the beauty of "(~R∊R∘.×R)/R←1↓ιR" ;-)

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Experts (#1, May 10 2018)
>>> Python Projects, Coaching and Consulting ...  http://www.egenix.com/
>>> Python Database Interfaces ...   http://products.egenix.com/
>>> Plone/Zope Database Interfaces ...   http://zope.egenix.com/


::: We implement business ideas - efficiently in both time and costs :::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
   Registered at Amtsgericht Duesseldorf: HRB 46611
   http://www.egenix.com/company/contact/
  http://www.malemburg.com/

___
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] Runtime assertion with no overhead when not active

2018-05-10 Thread Barry Scott


> On 7 May 2018, at 18:52, Guido van Rossum  wrote:
> 
> On Mon, May 7, 2018 at 6:24 AM, Serhiy Storchaka  > wrote:
> I just don't understand why you need a new keyword for writing runtime checks.
> 
> Oh, that's pretty clear. The OP wants to be able to turn these checks off 
> with some flag he can set/clear at runtime, and when it's off he doesn't want 
> to incur the overhead of evaluating the check. The assert statement has the 
> latter property, but you have to use -O to turn it off. He basically wants a 
> macro so that
> 
>   runtime_assert()
> 
> expands to
> 
>   if  and ():
>   raise AssertionError
> 
> In Lisp this would be easy. :-)

This idea requires the same sort of machinery in python that I was hoping for 
to implement the short circuit logging.

My logging example would be

log( control_flag, msg_expr )

expanding to:

if :
log_function(  )

Barry

___
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] PEP 572: about the operator precedence of :=

2018-05-10 Thread Terry Reedy

On 5/9/2018 11:33 PM, Guido van Rossum wrote:

I now think that the best way out is to rule `:=` in the top level 
expression of an expression statement completely 


I would like to be able to interactively enter

>>> a: = f(2,4)

to have 'a' echoed as well as bound.

--
Terry Jan Reedy

___
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] PEP 572: about the operator precedence of := (Guido van Rossum)

2018-05-10 Thread Angus Hollands
>
> Is there a more appropriate mechanism to showing support for a 'EXPR given
x = EXPR' approach, as suggested by Nick Coghlan? Then, keeping the binding
rules the same for statement assign, requiring parenthesis, would keep
things consistent. I personally prefer it to := for the reasons I mentioned
previously.
Angus Hollands

Message: 4
> Date: Wed, 9 May 2018 20:33:05 -0700
> From: Guido van Rossum 
> To: Python-Ideas 
> Subject: [Python-ideas] PEP 572: about the operator precedence of :=
> Message-ID:
> <
> cap7+vjjsdel0fwiydhrfkgfxgx-okkynfzyf3fhs+kkjb6d...@mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
>
> (I vaguely recall this has been brought up before, but I'm too lazy to find
> the subtread. So it goes.)
>
> PEP 572 currently seems to specify that when used in expressions, the
> precedence of `:=` is lower (i.e. it binds more tightly) than all operators
> except for the comma. I derive this from the single example `stuff = [[y :=
> f(x), x/y] for x in range(5)]`.
>
> >From this it would follow that `f(a := 1, a)` is equivalent to `a = 1;
> f(1,
> 1)`, and also that `(a := 1, a)` is equivalent to `a = 1; (1, 1)`.
> (Although M.A.L. objected to this.)
>
> But what should `a := 1, 1` at the top level (as a statement) do? On the
> one hand, analogy with the above suggest that it is equivalent to `a = 1;
> (1, 1)`. But on the other hand, it would be really strange if the following
> two lines had different meanings:
>
> a = 1, 1   # a = (1, 1)
> a := 1, 1  # a = 1; (1, 1)
>
> I now think that the best way out is to rule `:=` in the top level
> expression of an expression statement completely (it would still be okay
> inside parentheses, where it would bind tighter than comma).
>
> An alternative would be to make `:=` bind less tight than comma (like `=`)
> everywhere, so that `a := 1, 1` indeed meant the same as `a = 1, 1`. But
> that feels very wrong at least for the case `f(a := 1, 1)` -- I believe Tim
> already mentioned that we've been conditioned by keyword arguments to parse
> this as `f((a := 1), 1)`. (I could add to this that we have done various
> things to generator expression syntax to avoid ever having to deal with
> ambiguities like `a, a+1 for a in range(10)` or `a for a in x, y`.)
>
> Another alternative would be to always require parentheses around `:=`, so
> that we would have to write `f((a := 1), 1)`. That's unambiguous, but
> otherwise just gets on the nerves.
>
> --
> --Guido van Rossum (python.org/~guido)
> -- next part --
> An HTML attachment was scrubbed...
> URL: <
> http://mail.python.org/pipermail/python-ideas/attachments/20180509/41b36ded/attachment-0001.html
> >
>
> --
>
> Message: 5
> Date: Wed, 9 May 2018 22:35:05 -0500
> From: Raymond Hettinger 
> To: Facundo Batista 
> Cc: Python-Ideas 
> Subject: Re: [Python-ideas] Have a "j" format option for lists
> Message-ID: <67a74ea6-da5b-492c-9811-f995ef909...@gmail.com>
> Content-Type: text/plain;   charset=us-ascii
>
> On May 9, 2018, at 7:39 AM, Facundo Batista 
> wrote:
> >
> > This way, I could do:
> >
>  authors = ["John", "Mary", "Estela"]
>  "Authors: {:, j}".format(authors)
> > 'Authors: John, Mary, Estela'
> >
> ...
> >
> > What do you think?
>
> That is an inspired idea.  I like it :-)
>
>
> Raymond
>
>
>
>
> --
>
> Message: 6
> Date: Thu, 10 May 2018 13:42:05 +1000
> From: Chris Angelico 
> To: Python-Ideas 
> Subject: Re: [Python-ideas] PEP 572: about the operator precedence of
> :=
> Message-ID:
> <
> captjjmrwhhmidgq-h4fcbojqrp69evfkf2mbg1kyrh_w6ad...@mail.gmail.com>
> Content-Type: text/plain; charset="UTF-8"
>
> On Thu, May 10, 2018 at 1:33 PM, Guido van Rossum 
> wrote:
> > (I vaguely recall this has been brought up before, but I'm too lazy to
> find
> > the subtread. So it goes.)
> >
> > PEP 572 currently seems to specify that when used in expressions, the
> > precedence of `:=` is lower (i.e. it binds more tightly) than all
> operators
> > except for the comma. I derive this from the single example `stuff = [[y
> :=
> > f(x), x/y] for x in range(5)]`.
> >
> > From this it would follow that `f(a := 1, a)` is equivalent to `a = 1;
> f(1,
> > 1)`, and also that `(a := 1, a)` is equivalent to `a = 1; (1, 1)`.
> (Although
> > M.A.L. objected to this.)
> >
> > But what should `a := 1, 1` at the top level (as a statement) do? On the
> one
> > hand, analogy with the above suggest that it is equivalent to `a = 1; (1,
> > 1)`. But on the other hand, it would be really strange if the following
> two
> > lines had different meanings:
> >
> > a = 1, 1   # a = (1, 1)
> > a := 1, 1  # a = 1; (1, 1)
> >
> > I now think that the best way out is to rule `:=` in the top level