[Python-ideas] Re: `if-unless` expressions in Python

2019-06-24 Thread Greg Ewing

James Lu wrote:

I think

print("Remember to wear sunscreen!") if hot_outside unless Weather.is_raining()

Is more readable than

if hot_outside and not Weather.is_raining(): print("Remember to wear 
sunscreen!")


That's very much a matter of opinion -- I find the second version
considerably clearer.

--
Greg
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/XOOM2YNO2MEMJTFHGKRB3UOSPPJ5OVCG/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: `if-unless` expressions in Python

2019-06-24 Thread Jonathan Fine
I'm concerned that in this thread, and elsewhere, we're not paying
sufficient attention to https://en.wikipedia.org/wiki/Cognitive_load.

Adding a feature to a system can increase the cognitive load in
learning the system, and it can also reduce the cognitive load in
using the system. Sometimes adding a feature can reduce cognitive load
in both learning and using the system, but I suspect that is
exceptional.

I suggest that in this thread we have more discussion of the cognitive
load adding this feature would add to those learning the system. I
also suggest, as someone else has already done, that we focus more on
the problem to be solved rather than a specific solution.

-- 
Jonathan
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/HJDDLK57OUMAOYTJKDV7IPAIEJGQ3MMC/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: `if-unless` expressions in Python

2019-06-24 Thread Andrew Barnert via Python-ideas
On Jun 24, 2019, at 10:27, Dan Sommers <2qdxy4rzwzuui...@potatochowder.com> 
wrote:
> 
> On 6/24/19 12:32 PM, James Lu wrote:
> 
> > I think
> >
> > print("Remember to wear sunscreen!") if hot_outside unless 
> > Weather.is_raining()
> >
> > Is more readable than
> >
> > if hot_outside and not Weather.is_raining(): print("Remember to wear 
> > sunscreen!")
> 
> I disagree, but that's bound to happen in a discussion like this.

I also disagree. And I think there’s a principled reason for it.

In a language like Perl, where there’s little consistency in syntax and flow 
control is scattered all over the place, this would be great. You can write the 
code in the same order as the sentence you’re thinking in your native language. 
In fact, Perl added postfix conditionals back in version 4 or so, and everyone 
loved it.

But in Python, flow control is restricted to compound statements, which all 
have the same form: a colon and an indebted block. This makes Python a lot 
easier to read.

While it’s _possible_ to escape from an expression by intentionally calling a 
function that raises, or to bury side-effect-only function calls deep in an 
expression, it’s considered bad style, and only done in rare, exceptional 
cases. What’s being proposed here is to add a new way to do that. So, either 
it’s deliberately encouraging bad style, or it’s something that would be so 
rarely used that it’s not worth it. 

What about comprehensions? They _do_ have flow control within an expression, 
and even spell it with a postfix condition. But comprehensions are a highly 
restricted mini-language, where the only flow control possible is skipping, and 
the syntax encourages you to keep them short and simple. So they turn out to be 
worth it.

Which is exactly why the more restricted version of the proposal—only allowing 
“pass” (or however  it’s spelled) inside displays (and “tuple displays”) and 
argument lists—might be worth it, even if the fully general one isn’t.

That being said, I still haven’t seen an example of a function call or list 
display that actually looks compelling. I think if anyone wants to convince 
everyone that some form of this proposal is worthwhile, that’s the first thing 
they need to provide.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/BGFUVTYMDHI27QAQ6XA6ZK677JOD44HV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: `if-unless` expressions in Python

2019-06-24 Thread Dan Sommers

On 6/24/19 12:32 PM, James Lu wrote:

> I think
>
> print("Remember to wear sunscreen!") if hot_outside unless 
Weather.is_raining()

>
> Is more readable than
>
> if hot_outside and not Weather.is_raining(): print("Remember to wear 
sunscreen!")


I disagree, but that's bound to happen in a discussion like this.

> I think the unless syntax would be especially useful when there is a
> series of functions like this.
>
> The general use case would be:
>
> side_effecting_expression if frequent_condition unless rare_condition

Can you clarify "series of functions like this"?  Are the functions the
calls to print?  Are the functions the calls to Weather.is_raining()?

IMO, in a "series of logic like this," the fact that individual bits are
the same should be blindingly obvious.  With line after line of multiple
bits (some side-effecting statement, two conditions, and some keywords),
as opposed to a series of if statements with their associated inddented
suites, I feel that the commonality will get lost.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/JNZ3CGYGCNEHCVIKR7DHINSEJN4DEE5U/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: `if-unless` expressions in Python

2019-06-24 Thread MRAB

On 2019-06-24 17:32, James Lu wrote:

I think

print("Remember to wear sunscreen!") if hot_outside unless Weather.is_raining()

Is more readable than

if hot_outside and not Weather.is_raining(): print("Remember to wear 
sunscreen!")

I think the unless syntax would be especially useful when there is a series of 
functions like this.

The general use case would be:

side_effecting_expression if frequent_condition unless rare_condition

Python isn't English, and I don't think we should be pushing it in that 
direction.

___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/RWL3VFX6Q5PSWARHNLBPHNCB3XW2RGF3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: `if-unless` expressions in Python

2019-06-24 Thread Chris Angelico
On Tue, Jun 25, 2019 at 3:01 AM James Lu  wrote:
>
> I think
>
> print("Remember to wear sunscreen!") if hot_outside unless 
> Weather.is_raining()
>
> Is more readable than
>
> if hot_outside and not Weather.is_raining(): print("Remember to wear 
> sunscreen!")
>
> I think the unless syntax would be especially useful when there is a series 
> of functions like this.
>
> The general use case would be:
>
> side_effecting_expression if frequent_condition unless rare_condition

Can you find some non-toy examples where this forked condition is
actually better than simply using a boolean operator?

ChrisA
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/LCTBWDA4NFF4O66G2FY5EI5MJFVQBGDA/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: `if-unless` expressions in Python

2019-06-24 Thread Steven D'Aprano
Folks,

Can I please remind people to trim their quoting? We readers shouldn't 
have to hit the Page Down key eight or nine times, or scroll down 
through five or six pages, to see the first new content.

(I have a rule: if I haven't reached new content after nine screens of 
quoting, I give up and delete the email.)

Quoting is supposed to show context, not to be a full record of the 
entire history of the thread. We have archives for that :)

If you really can't trim the quoting (backspace key broken? feeble email 
client?) then speaking for myself, I'd rather you top-post so at least I 
can see your comments within a page or two of the start of the email.

Thank you,

Steven
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/FXDQ4RMSQJLO2V7DFQJ4CYDAM4X5TLY3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: `if-unless` expressions in Python

2019-06-24 Thread MRAB
On 2019-06-24 09:23, Chris Angelico wrote:> On Mon, Jun 24, 2019 at 6:03 
PM Andrew Barnert  wrote:

>>
>> On Sunday, June 23, 2019, 10:13:07 PM PDT, Chris Angelico 
 wrote:

>>
>> > The biggest problem with this proposal is the way that, being a
>> > syntactic construct, it's going to be non-composable.
>>
>> > # Oops, syntax error
>> > with (some_expr as q,
>> > some_other_expr as w):
>> > pass
>>
>> I don't understand. Are you suggesting that some_expr could be 
something like "2 if cond else pass", so if not cond, this is supposed 
to be equivalent to "with ( as q, some_other_expr as w):", which is a 
SyntaxError (at runtime)? If so, that's the same problem as with most 
other syntactic locations where an expression can go, like the 
assignment example I gave earlier.

>>
>
> Sorry, I kinda glossed over a lot of details there.
>
> The example that I gave is a SyntaxError, unrelated to the current
> proposal. To make it work, you have to remove the parens, and use a
> backslash to continue the line. And every now and then, someone
> proposes to make the 'with' statement accept the form I gave, because
> it would be cleaner. It isn't an easy change, because "with expr as
> name" is a syntactic construct; the "expr as name" part cannot be
> composed into a larger expression.
>
> The proposed syntax would have the exact same problem:
>
> stuff = [
>  foo unless True,
>  bar unless False,
>  (quux("spam", "eggs", "sausage", "spam")
>  unless customer_wants("spam"))
> ]
>
> This particular example would work if you just removed the parens (it
> doesn't need a backslash to continue the line, since it's inside a
> list display), but I can pretty much guarantee that people will put
> parens around one of these sequences and then wonder why on earth it
> doesn't work.
>
Well, I suppose it could work with parentheses, but not necessarily in 
the way you want/expect. If customer_wants("spam") returns False, then 
(quux("spam", "eggs", "sausage", "spam") unless customer_wants("spam")) 
could mean ()! (You could say that it doesn't, and if you want that 
behaviour then you should add a trailing comma.)

___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/3Q3GVWFCQXEBDGQ2QYWQEQBEESYE6WJK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Integer infinity and extended integers

2019-06-24 Thread Neil Girdhar
Now that Python is beginning to embrace type annotations, is it worth 
revisiting the idea of having extended integers and an integer infinity?

I found myself trying to annotate this line:

events_to_do: Union[int, float] = math.inf

where I am only including float in the union to accommodate math.inf.  

I'm interested in exploring this concrete proposal:

Add a class to the numeric hierarchy 
(https://www.python.org/dev/peps/pep-3141/) ExtendedIntegral whereby  Real 
:> ExtendedIntegral :> Integral.
Add a sentinel math.int_inf that obeys all of the same kinds of rules as 
math.inf does.

Then, I could annotate more simply:

events_to_do: ExtendedIntegral = math.int_inf

With respect to Python, this is discussed somewhat 
here 
https://stackoverflow.com/questions/24587994/infinite-integer-in-python/35725065#35725065.

The name "extended integer" is discussed somewhat 
here https://math.stackexchange.com/questions/1442961/extended-integers.  A 
quick search of papers shows that it is sometimes used in this 
sense: https://scholar.google.com/scholar?q=%22extended+integer

Best,

Neil
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/QFLWTFJMU2RSGBMYP2XMSYA36VYFRDDQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: `if-unless` expressions in Python

2019-06-24 Thread Chris Angelico
On Mon, Jun 24, 2019 at 6:03 PM Andrew Barnert  wrote:
>
> On Sunday, June 23, 2019, 10:13:07 PM PDT, Chris Angelico  
> wrote:
>
> > The biggest problem with this proposal is the way that, being a
> > syntactic construct, it's going to be non-composable.
>
> > # Oops, syntax error
> > with (some_expr as q,
> > some_other_expr as w):
> > pass
>
> I don't understand. Are you suggesting that some_expr could be something like 
> "2 if cond else pass", so if not cond, this is supposed to be equivalent to 
> "with ( as q, some_other_expr as w):", which is a SyntaxError (at runtime)? 
> If so, that's the same problem as with most other syntactic locations where 
> an expression can go, like the assignment example I gave earlier.
>

Sorry, I kinda glossed over a lot of details there.

The example that I gave is a SyntaxError, unrelated to the current
proposal. To make it work, you have to remove the parens, and use a
backslash to continue the line. And every now and then, someone
proposes to make the 'with' statement accept the form I gave, because
it would be cleaner. It isn't an easy change, because "with expr as
name" is a syntactic construct; the "expr as name" part cannot be
composed into a larger expression.

The proposed syntax would have the exact same problem:

stuff = [
foo unless True,
bar unless False,
(quux("spam", "eggs", "sausage", "spam")
unless customer_wants("spam"))
]

This particular example would work if you just removed the parens (it
doesn't need a backslash to continue the line, since it's inside a
list display), but I can pretty much guarantee that people will put
parens around one of these sequences and then wonder why on earth it
doesn't work.

ChrisA
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/NGFOPEENZQMELX4SVVKU2NQNQXEBS3CU/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: `if-unless` expressions in Python

2019-06-24 Thread Andrew Barnert via Python-ideas
On Sunday, June 23, 2019, 10:13:07 PM PDT, Chris Angelico  
wrote:
 
> The biggest problem with this proposal is the way that, being a
> syntactic construct, it's going to be non-composable.

> # Oops, syntax error
> with (some_expr as q,
>         some_other_expr as w):>     pass
I don't understand. Are you suggesting that some_expr could be something like 
"2 if cond else pass", so if not cond, this is supposed to be equivalent to 
"with ( as q, some_other_expr as w):", which is a SyntaxError (at runtime)? If 
so, that's the same problem as with most other syntactic locations where an 
expression can go, like the assignment example I gave earlier.
Anyway, I think we need to make this more concrete. Python semantics aren't 
defined in terms of syntax rewriting rules, so trying to discuss this 
suggestion as if it were a syntax rewriting rule is only going to lead to 
confusion. 
If the restrictions on pass are to be syntactic, they're in the grammar, and "x 
= 2 if cond else pass" is a SyntaxError, at compile time, because it's not 
valid syntax for an assignment statement. If not, then they're defined in the 
semantics attached to the grammar; "x = 2 if cond else pass" is a valid 
assignment statement, whether cond is true or false, and some node in that 
statement's tree is going to tell us what it means—in this case, that it raises 
some error (let's all it NoValueError) at runtime if cond is false.
Either way, I think you want to start with a restricted set of places pass can 
be used or propagated. If it's possible (and I'm pretty sure it is), it's much 
easier to just define the changed behavior of a handful of nodes we care about, 
than to grub through the entire language looking at how each construct would 
handle it. (Plus, you'd definitely want to be conservative here—adding 
pass-handling to return statement or or expressions in a later version breaks 
nothing, but removing it breaks working code.)
So, pass has to change from a statement to an expression. And then you need to 
define the semantics of a few things: the new pass expression, the handful of 
places where you want pass is meaningful as a final value (I believe that's 
just 6.2.4 displays, 6.3.4 calls, 6.14 expression lists, and 7.1 expression 
statements), and the handful of places where pass can propagate up (that could 
be just 6,12 conditionals). For example, in 6.14, you change the first 
paragraph to say "… number of expressions in the list **that do not evaluate to 
pass**." In 6.12, you add "… y is evaluated and its value is returned. **In 
this case, if y evaluates to pass, the conditional evaluates to pass.**"
If it's not syntactic, then you're almost done, you just need to add a new 
blanket rule that says that when an expression evaluates to pass in all cases 
except as specified otherwise, then a NoValueError is raised. So, "x = 1, 2 if 
spam else pass, 3" evaluates to (1, 3) when not spam because the semantics for 
expression list (and conditional expression) tell us what happen; "x = 2 if 
spam else pass" raises a NoValueError because assignment and expression don't 
specify otherwise.
If it is syntactic, then you don't need that all-other-cases bit, and don't 
need the exception at all. Instead, you need to change the grammar in 6.12 and 
friends to use a new node called pass_expression instead of expression, and 
that node can include pass_conditional_expression instead of 
conditional_expression, and… propagate that forking as far into the grammar as 
you have to. Nw, "x = 2 if spam else pass" is a SyntaxError because "2 if spam 
else pass" is not an expression, but "x = 1, 2 if spam else pass, 3" is valid 
syntax because "2 if spam else pass" is a valid pass_expression, and therefore 
a valid starred_item, and therefore the whole list is a valid starred_list 
(which, at runtime, will be either (1, 3) or (1, 2, 3)), and therefore the 
statement is valid. I'm not sure how many nodes are in that "as far into the 
grammar as you have to", but each change is trivial; it's just a bit tedious to 
walk the whole graph, and since I'm -1 on the proposal, I'm not going to do it. 
 ___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/IUDJE4G6XWODP7TPOKZOKJUHIDTMCU2X/
Code of Conduct: http://python.org/psf/codeofconduct/