Re: Conditional 1-line expression in python (Dom Grigonis)
Hello all, Please Dom Grigonis add choices : - "No preference" choice to first question - "I don't know" or "I can't tell" to third question And I will answer to your poll and probably other people will feel and do the same. I agree that question 2 makes me prefer C syntax. But C is not the nicest syntax in my point of view. In MySQL SQL, there is IF(condition, if_result, else_result) which I find nice. Moreover, it fits well with black style of formatting: foo_var = IF( this_is_a very_long_condition_expression_which_may_have_nested_parts, this_is_a very_long_if_result_expression_which_may_have_nested_parts, this_is_a very_long_else_result_expression_which_may_have_nested_parts, ) to compare with : foo_var = ( this_is_a very_long_condition_expression_which_may_have_nested_parts, ? this_is_a very_long_if_result_expression_which_may_have_nested_parts, : this_is_a very_long_else_result_expression_which_may_have_nested_parts, ) I can enjoy both, but I prefer the SQL apart from the fact that "IF" keyword would be ambiguous. I also enjoy very much : foo_var = CASE WHEN condition THEN if_result WHEN condition2 THEN elif_result ELSE else_result END from SQL. And CASE is not a reserved keyword and WHEN, THEN, ELSE could have specific meaning inside of case. Truly, I would enjoy the following syntax for Python à la black : foo_var = case( when condition then if_result when condition2 then elif_result else else_result ) or even more concise and still readable : foo_var = case( condition : if_result, condition2 : elif_result, else_result, ) Best regards, Laurent Lyaudet Le lun. 17 juil. 2023 à 22:42, <python-ideas-request@python.org> a écrit :
Message: 2 Date: Mon, 17 Jul 2023 23:41:25 +0300 From: Dom Grigonis <dom.grigonis@gmail.com> Subject: [Python-ideas] Conditional 1-line expression in python To: python-ideas <python-ideas@python.org> Message-ID: <31303E8B-05A4-408B-AF4D-916F805B5966@gmail.com> Content-Type: multipart/alternative; boundary="Apple-Mail=_41C44739-410D-45EA-89FF-6E2F1AF86836"
Hi everyone,
I am not very keen on long discussions on such matter as I do not think there is much to discuss: there is no technical complexity in it and it doesn’t really change or introduce anything new. It is only a matter of opinion & style/design preferences with respect to logical order and brevity of a statement.
So I thought, if anyone can be bothered on such question and instead of writing 3-minute e-mail, would take few seconds to answer 3-question poll.
https://q5yitzu62.supersurvey.com <https://q5yitzu62.supersurvey.com/>
Would be interesting to see if my preference is an outlier or not really.
Kind regards, D. Grigonis
Ah, I can’t do that post-publish. This will have to suffice for now. If this got to a point where there was a case to revise 2005 decision or introduce an alternative (which I very much doubt can happen any time soon), much more elaborate research and survey would have to be done and all options considered. I like `IF(cond, true, false)`, even better than `ifelse(cond, true, false)` - shorter. But in python this would indicate a function call, meaning all arguments would need to be evaluated before the expression logic. If evaluation is not costly, one can simply use his own function to do this. I still feel that compared to list comprehension and other functional and elegant python constructs, python's if-else expression is lacking. I often choose to go multi-line much more verbose code as opposed to more brief constructs just because it becomes unreadable - a more elegant and logically convenient expression would change the decision ratio significantly, at least for me. Your examples nicely emphasise it. Another perspective: # Code becomes easily read when there is a nice alignment in horizontal space. e.g.: variable = None length_1 = None somethin = None # I often take this into account on variable name selection. Now: foo = var1 if a == 0 else default bar = variable2 if a == 0 else default2 # As opposed to foo = a == 0 ? var1 : default bar = a == 0 ? variable2 : default2 # Naturally, one can argue: what if condition length differs - same problem. # But in practice, the number of conditionals is greatly smaller than variables. # Thus, much more easier to adapt to that. Although, the argument that python is meant to be read as english is very much valid, but I do not see why it has to be an overarching one if the opportunity cost of it is too great in other dimensions. Finally, it is always an option to have 2 conditional expressions. Maybe another python expression which is a superset of current `ifelse`. Just not sure what it could be and what other gaps or extensions it could fill. From what I have gathered, these: https://peps.python.org/pep-0505/ <https://peps.python.org/pep-0505/> https://peps.python.org/pep-0463/ <https://peps.python.org/pep-0463/> , and certain number of proposals in this group at their root are pointing approximately to the same direction. I.e. some things are too verbose (and too many lines of code) given the simplicity of what is needed to be done. https://peps.python.org/pep-0308/#detailed-results-of-voting <https://peps.python.org/pep-0308/#detailed-results-of-voting> It seems that C’s expression was ranked 2nd most favourable… The decision was 3rd. This kinda suggests that I am not as delusional as I initially thought I might appear to be with this... The initial proposal wasn’t too bad - I could work with it. Being in line with a sequential logic of multiline `if-else` statement is a plus. (if <condition>: <expression1> else: <expression2>)
On 18 Jul 2023, at 00:36, Laurent Lyaudet <laurent.lyaudet@gmail.com> wrote:
Hello all,
Please Dom Grigonis add choices : - "No preference" choice to first question - "I don't know" or "I can't tell" to third question And I will answer to your poll and probably other people will feel and do the same. I agree that question 2 makes me prefer C syntax. But C is not the nicest syntax in my point of view. In MySQL SQL, there is IF(condition, if_result, else_result) which I find nice. Moreover, it fits well with black style of formatting: foo_var = IF( this_is_a very_long_condition_expression_which_may_have_nested_parts, this_is_a very_long_if_result_expression_which_may_have_nested_parts, this_is_a very_long_else_result_expression_which_may_have_nested_parts, ) to compare with : foo_var = ( this_is_a very_long_condition_expression_which_may_have_nested_parts, ? this_is_a very_long_if_result_expression_which_may_have_nested_parts, : this_is_a very_long_else_result_expression_which_may_have_nested_parts, ) I can enjoy both, but I prefer the SQL apart from the fact that "IF" keyword would be ambiguous. I also enjoy very much : foo_var = CASE WHEN condition THEN if_result WHEN condition2 THEN elif_result ELSE else_result END from SQL. And CASE is not a reserved keyword and WHEN, THEN, ELSE could have specific meaning inside of case. Truly, I would enjoy the following syntax for Python à la black : foo_var = case( when condition then if_result when condition2 then elif_result else else_result ) or even more concise and still readable : foo_var = case( condition : if_result, condition2 : elif_result, else_result, )
Best regards, Laurent Lyaudet
Le lun. 17 juil. 2023 à 22:42, <python-ideas-request@python.org> a écrit :
Message: 2 Date: Mon, 17 Jul 2023 23:41:25 +0300 From: Dom Grigonis <dom.grigonis@gmail.com> Subject: [Python-ideas] Conditional 1-line expression in python To: python-ideas <python-ideas@python.org> Message-ID: <31303E8B-05A4-408B-AF4D-916F805B5966@gmail.com> Content-Type: multipart/alternative; boundary="Apple-Mail=_41C44739-410D-45EA-89FF-6E2F1AF86836"
Hi everyone,
I am not very keen on long discussions on such matter as I do not think there is much to discuss: there is no technical complexity in it and it doesn’t really change or introduce anything new. It is only a matter of opinion & style/design preferences with respect to logical order and brevity of a statement.
So I thought, if anyone can be bothered on such question and instead of writing 3-minute e-mail, would take few seconds to answer 3-question poll.
https://q5yitzu62.supersurvey.com <https://q5yitzu62.supersurvey.com/>
Would be interesting to see if my preference is an outlier or not really.
Kind regards, D. Grigonis
On Tue, 18 Jul 2023 at 08:34, Dom Grigonis <dom.grigonis@gmail.com> wrote:
I still feel that compared to list comprehension and other functional and elegant python constructs, python's if-else expression is lacking. I often choose to go multi-line much more verbose code as opposed to more brief constructs just because it becomes unreadable - a more elegant and logically convenient expression would change the decision ratio significantly, at least for me.
You choose to go multi-line because the one-liner becomes less readable? Then that's a win for the current system. This is NOT a problem to be solved. Everything is working correctly. You have chosen the readable option over the compact one!
# Code becomes easily read when there is a nice alignment in horizontal space. e.g.:
variable = None length_1 = None somethin = None
variable = length_1 = somethin = None
# I often take this into account on variable name selection. Now:
Poor choice IMO. You could have had more consistent variable names by taking advantage of chained assignment.
foo = var1 if a == 0 else default bar = variable2 if a == 0 else default2
# As opposed to
foo = a == 0 ? var1 : default bar = a == 0 ? variable2 : default2
As opposed to if a == 0: foo, bar = var1, variable2 else: foo, bar = default, default2
From what I have gathered, these: https://peps.python.org/pep-0505/ https://peps.python.org/pep-0463/ , and certain number of proposals in this group at their root are pointing approximately to the same direction. I.e. some things are too verbose (and too many lines of code) given the simplicity of what is needed to be done.
Both of those are about *expressiveness*. This is not the same thing as compactness. The two do sometimes align but the purpose is different.
https://peps.python.org/pep-0308/#detailed-results-of-voting It seems that C’s expression was ranked 2nd most favourable… The decision was 3rd. This kinda suggests that I am not as delusional as I initially thought I might appear to be with this...
Like I said, people who are *already familiar with* C's syntax find it more comfortable than those who are not. But also - this ship has sailed. There's not a lot of point discussing this. If Python had decided against having any conditional expression, then maybe you could reopen the discussion (and I'll be honest, it would have been reopened already by now); but we have a perfectly good conditional expression, so the chances of getting a duplicate syntax added are slim to Buckley's. Adding another way of writing the same thing doesn't materially improve expressiveness. ChrisA
# Code becomes easily read when there is a nice alignment in horizontal space. e.g.:
variable = None length_1 = None somethin = None
variable = length_1 = somethin = None
Obviously they would not all be None, just chosen None as `any dummy value`, mistake on my part - None is not suitable for that.
foo = var1 if a == 0 else default bar = variable2 if a == 0 else default2
# As opposed to
foo = a == 0 ? var1 : default bar = a == 0 ? variable2 : default2
As opposed to
if a == 0: foo, bar = var1, variable2 else: foo, bar = default, default2
Again, one is `a == 0`, another is `b == 0`. I didn’t do a good job conveying this did I… Will try to be more precise and leave less room for misinterpretation. foo = foo3 if foo2 == 0 else default bar = barbarbar if bar2 == 0 else default2 # As opposed to foo = foo2 == 0 ? foo3 : default bar = bar2 == 0 ? barbarbar : default2
From what I have gathered, these: https://peps.python.org/pep-0505/ https://peps.python.org/pep-0463/ , and certain number of proposals in this group at their root are pointing approximately to the same direction. I.e. some things are too verbose (and too many lines of code) given the simplicity of what is needed to be done.
Both of those are about *expressiveness*. This is not the same thing as compactness. The two do sometimes align but the purpose is different.
I don’t think it is that easy to draw the line here. Everything in both of those PEPs can be expressed using current constructs. So maybe they are about more compact expressions? Same as proposal regarding more expressive dict.get from which my train of thought has started. Is it a request for: a) more expressive dict.get? b) more concise way do what can be done in a several lines of code anyways? I just can’t see any substance that you are coming from with this… Was python made for conciseness or expressiveness? Everything it does can already be done in C isn’t it? So I would argue any abstraction is really more about conciseness. Expressiveness is more about incorporation of what is already there, but not in the abstraction, i.e. extension. But python being interpreted language written in another language, I really FAIL to see how is all of this NOT about conciseness and modularity? I agree that there are other dimensions, but I always thought python being closer to unix than windows...
On 18 Jul 2023, at 03:08, Chris Angelico <rosuav@gmail.com> wrote:
On Tue, 18 Jul 2023 at 08:34, Dom Grigonis <dom.grigonis@gmail.com> wrote:
I still feel that compared to list comprehension and other functional and elegant python constructs, python's if-else expression is lacking. I often choose to go multi-line much more verbose code as opposed to more brief constructs just because it becomes unreadable - a more elegant and logically convenient expression would change the decision ratio significantly, at least for me.
You choose to go multi-line because the one-liner becomes less readable? Then that's a win for the current system. This is NOT a problem to be solved. Everything is working correctly. You have chosen the readable option over the compact one!
# Code becomes easily read when there is a nice alignment in horizontal space. e.g.:
variable = None length_1 = None somethin = None
variable = length_1 = somethin = None
# I often take this into account on variable name selection. Now:
Poor choice IMO. You could have had more consistent variable names by taking advantage of chained assignment.
foo = var1 if a == 0 else default bar = variable2 if a == 0 else default2
# As opposed to
foo = a == 0 ? var1 : default bar = a == 0 ? variable2 : default2
As opposed to
if a == 0: foo, bar = var1, variable2 else: foo, bar = default, default2
From what I have gathered, these: https://peps.python.org/pep-0505/ https://peps.python.org/pep-0463/ , and certain number of proposals in this group at their root are pointing approximately to the same direction. I.e. some things are too verbose (and too many lines of code) given the simplicity of what is needed to be done.
Both of those are about *expressiveness*. This is not the same thing as compactness. The two do sometimes align but the purpose is different.
https://peps.python.org/pep-0308/#detailed-results-of-voting It seems that C’s expression was ranked 2nd most favourable… The decision was 3rd. This kinda suggests that I am not as delusional as I initially thought I might appear to be with this...
Like I said, people who are *already familiar with* C's syntax find it more comfortable than those who are not.
But also - this ship has sailed. There's not a lot of point discussing this. If Python had decided against having any conditional expression, then maybe you could reopen the discussion (and I'll be honest, it would have been reopened already by now); but we have a perfectly good conditional expression, so the chances of getting a duplicate syntax added are slim to Buckley's. Adding another way of writing the same thing doesn't materially improve expressiveness.
ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@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/DUPGM2... Code of Conduct: http://python.org/psf/codeofconduct/
On Tue, 18 Jul 2023 at 10:37, Dom Grigonis <dom.grigonis@gmail.com> wrote:
As opposed to
if a == 0: foo, bar = var1, variable2 else: foo, bar = default, default2
Again, one is `a == 0`, another is `b == 0`. I didn’t do a good job conveying this did I… Will try to be more precise and leave less room for misinterpretation.
Would you really go through and change all your variable names if it turns out that what you actually need is "a == 0" and "b == 15"? This sort of alignment is so fragile and unnecessary. Yes, it's nice when it works out, but it should never be a high priority.
foo = foo3 if foo2 == 0 else default bar = barbarbar if bar2 == 0 else default2
# As opposed to
foo = foo2 == 0 ? foo3 : default bar = bar2 == 0 ? barbarbar : default2
Extremely artificial. You've shown that, if the conditions are the same lengths but the "if-true" expressions aren't, you can align them using ?: and can't align them using if-else. It's just as valid to show: foo = "yes" if foo2 else "no" bar = "yes" if barbarbar else "no" Like I said, extremely fragile.
I don’t think it is that easy to draw the line here. Everything in both of those PEPs can be expressed using current constructs. So maybe they are about more compact expressions?
"Can be expressed"? Well, yes. Python is Turing-complete. So is Brainf*. Doesn't mean we want to use it though. Expressiveness is a spectrum or a scale. You can improve on it without the older version being impossible to write. In fact, Python really doesn't NEED all the syntax it has. Have a read of this series of blog posts: https://snarky.ca/tag/syntactic-sugar/ (Brett Cannon also did a talk on this at PyCon US 2023; not sure if that's been made public yet.) There are only a handful of pieces of syntax that you really can't do without. But you CAN skip having an "if" statement. No kidding - you can eliminate the if statement by smart use of the while statement. https://snarky.ca/unravelling-if-statements/ Improvements to expressiveness allow us to write better code, to make it clearer what the *programmer's intent* is. Sometimes that aligns with compactness; sometimes it doesn't.
Was python made for conciseness or expressiveness? Everything it does can already be done in C isn’t it? So I would argue any abstraction is really more about conciseness. Expressiveness is more about incorporation of what is already there, but not in the abstraction, i.e. extension. But python being interpreted language written in another language, I really FAIL to see how is all of this NOT about conciseness and modularity?
Expressiveness. It's about how well the source code represents the programmer's intent. You could write all of your code as a massive matrix of logic gates, but that wouldn't improve readability. And since you can implement logic gates with water - see https://www.youtube.com/watch?v=IxXaizglscw for proof - your program source code could be an acrylic sheet with a bunch of buckets glued onto it. But none of us want to write code like that, and definitely none of us want to read code like that. ChrisA
Much of what you respond to me indicates that you did not properly read what I have written and did not really understand where I am coming from.
On 18 Jul 2023, at 04:04, Chris Angelico <rosuav@gmail.com> wrote:
On Tue, 18 Jul 2023 at 10:37, Dom Grigonis <dom.grigonis@gmail.com> wrote:
As opposed to
if a == 0: foo, bar = var1, variable2 else: foo, bar = default, default2
Again, one is `a == 0`, another is `b == 0`. I didn’t do a good job conveying this did I… Will try to be more precise and leave less room for misinterpretation.
Would you really go through and change all your variable names if it turns out that what you actually need is "a == 0" and "b == 15"? This sort of alignment is so fragile and unnecessary. Yes, it's nice when it works out, but it should never be a high priority.
foo = foo3 if foo2 == 0 else default bar = barbarbar if bar2 == 0 else default2
# As opposed to
foo = foo2 == 0 ? foo3 : default bar = bar2 == 0 ? barbarbar : default2
Extremely artificial. You've shown that, if the conditions are the same lengths but the "if-true" expressions aren't, you can align them using ?: and can't align them using if-else. It's just as valid to show:
foo = "yes" if foo2 else "no" bar = "yes" if barbarbar else "no"
Like I said, extremely fragile.
I don’t think it is that easy to draw the line here. Everything in both of those PEPs can be expressed using current constructs. So maybe they are about more compact expressions?
"Can be expressed"? Well, yes. Python is Turing-complete. So is Brainf*. Doesn't mean we want to use it though.
Expressiveness is a spectrum or a scale. You can improve on it without the older version being impossible to write. In fact, Python really doesn't NEED all the syntax it has. Have a read of this series of blog posts:
https://snarky.ca/tag/syntactic-sugar/
(Brett Cannon also did a talk on this at PyCon US 2023; not sure if that's been made public yet.) There are only a handful of pieces of syntax that you really can't do without. But you CAN skip having an "if" statement. No kidding - you can eliminate the if statement by smart use of the while statement. https://snarky.ca/unravelling-if-statements/
Improvements to expressiveness allow us to write better code, to make it clearer what the *programmer's intent* is. Sometimes that aligns with compactness; sometimes it doesn't.
Was python made for conciseness or expressiveness? Everything it does can already be done in C isn’t it? So I would argue any abstraction is really more about conciseness. Expressiveness is more about incorporation of what is already there, but not in the abstraction, i.e. extension. But python being interpreted language written in another language, I really FAIL to see how is all of this NOT about conciseness and modularity?
Expressiveness. It's about how well the source code represents the programmer's intent. You could write all of your code as a massive matrix of logic gates, but that wouldn't improve readability. And since you can implement logic gates with water - see https://www.youtube.com/watch?v=IxXaizglscw for proof - your program source code could be an acrylic sheet with a bunch of buckets glued onto it.
But none of us want to write code like that, and definitely none of us want to read code like that.
ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@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/B5YRPP... Code of Conduct: http://python.org/psf/codeofconduct/
On 18/07/23 10:30 am, Dom Grigonis wrote:
Although, the argument that python is meant to be read as english is very much valid, but I do not see why it has to be an overarching one if the opportunity cost of it is too great in other dimensions.
It's not overarching. Many things in Python don't read like English, and nobody is suggesting changing them to be more English-like. I think you've got it backwards here. The fact that it reads like English is just a possible explanation of why many people find it more readable. The fact that people (well, just Guido at that time) find it readable is the reason it was chosen, not beause it's English-like. -- Greg
Ok, thanks. I think what I am aiming at is that there is a pool of suggestions and PEPs that are pointing towards very similar direction and I find myself often wandering in the same space, just trying to figure out what it exactly is. It sometimes feels more verbose than it could be for what it is in the context of how simple python is to use in general. I am fully well aware that current if-else expression is not going anywhere. Chances that another expression is introduced, which does exactly the same thing are close to none. So I am just gauging if it is a matter of conciseness of existing expressions or absence of something that could be there. Conditional if-else is just a place where I got to naturally. Got some useful references to PEPs, python history and opinions. Maybe it will become more clear in the future or maybe something new is already being worked that is going to fill the gap which I am not aware of. I haven’t even started any proposal myself, I was just following e-mail requests and rejected PEPs that were mentioned here. Combined it with my own experience and this is where I got to. Currently seems like it’s a dead end. Decision’s have been made, opinions taken into account, but I still have to write either: a) awkward 1-liner self.value = value if value is not None else DefaultClass() b) 3 nicely readable lines with 1 unnecessary assignment. self.value = value if value is None: self.value = DefaultClass() c) 4 lines, no unnecessary assignments with excellent readability. if value is None: self.value = DefaultClass() else: self.value = value The issue with b) and c) is that if I use those ones, my constructors become unbearably long and finally lead to the point where development becomes awkward. I would think that for what it does, it shouldn’t be more than 1 line. Max - 2. But a) is somewhat awkward. All (well not all, just several things) taken into account I ended up at inconvenience of `ifelse` expression, which would make a) my natural choice in this case. I am not even suggesting to introduce analogous `ifelse` with different syntax, just trying to get some ideas, references, opinions or alternatives that I don’t know about. Maybe I need to spend some time on it and some solution will come out using existing python’s functionality or an idea which actually has a chance of being considered. How would you write this? Doesn’t the below feel more verbose than it could be? Add 10 more constructor argument and there are 50 lines of code that do pretty much nothing. Not very pythonic…? One-line conditionals aren’t very readable (to me! I am aware that some might not feel this way) and for longer variable names sometimes don’t even fit into 80 characters. def __init__(self, arg1=None, argument2=None, arg3foo=None, ...) if arg1 is None: self.arg1 = DefaultClass() else: self.arg1 = arg1 if argument2 is None: self.argument2 = DefaultClass() else: self.argument2 = argument2 if arg3foo is None: self.arg3foo = DefaultClass() else: self.arg3foo = arg3foo ... PEP505 would solve this nicely, but it only applies to None and would not apply to say user-defined sentinels and many other cases where permutations of different conditionals arise. Just want to stress out, that I know that this is something very primitive and might seem insubstantial to consider, but to me personally, solution to this would make a very big difference. I have been stuck on many such decisions of best practice and I have found satisfactory solutions to seemingly much more complex `problems` and am fairly happy having found optimal ways to do many different things in python - makes life easy. But this one is of very few that still bother me to this day. And it does seem related to certain queries that arise here. So just trying to see what others think, etc, etc Ok, I have been repeating myself for a bit, but from certain responses it felt like I have failed to convey where I am coming from. Or maybe no-one else has issue here, so if I am actually alone that is so bothered about this, it as also good information.
On 18 Jul 2023, at 04:40, Greg Ewing <gcewing@snap.net.nz> wrote:
On 18/07/23 10:30 am, Dom Grigonis wrote:
Although, the argument that python is meant to be read as english is very much valid, but I do not see why it has to be an overarching one if the opportunity cost of it is too great in other dimensions.
It's not overarching. Many things in Python don't read like English, and nobody is suggesting changing them to be more English-like.
I think you've got it backwards here. The fact that it reads like English is just a possible explanation of why many people find it more readable. The fact that people (well, just Guido at that time) find it readable is the reason it was chosen, not beause it's English-like.
-- Greg
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@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/ZVVK5A... Code of Conduct: http://python.org/psf/codeofconduct/
On Tue, 18 Jul 2023 at 14:07, Dom Grigonis <dom.grigonis@gmail.com> wrote:
PEP505 would solve this nicely, but it only applies to None and would not apply to say user-defined sentinels and many other cases where permutations of different conditionals arise.
PEP 671 would solve this nicely too. ChrisA
Yes, thank you, this would definitely be nice to have. Although, "A generic system for deferred evaluation has been proposed at times“ sound better if it was a superset of PEP505. Could you refer me to any resources about such considered system?
On 18 Jul 2023, at 08:33, Chris Angelico <rosuav@gmail.com> wrote:
On Tue, 18 Jul 2023 at 14:07, Dom Grigonis <dom.grigonis@gmail.com> wrote:
PEP505 would solve this nicely, but it only applies to None and would not apply to say user-defined sentinels and many other cases where permutations of different conditionals arise.
PEP 671 would solve this nicely too.
ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@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/R4HVE2... Code of Conduct: http://python.org/psf/codeofconduct/
On Tue, 18 Jul 2023 at 16:25, Dom Grigonis <dom.grigonis@gmail.com> wrote:
Yes, thank you, this would definitely be nice to have.
Although, "A generic system for deferred evaluation has been proposed at times“ sound better if it was a superset of PEP505. Could you refer me to any resources about such considered system?
Hrm, you'd probably have to scour the archives. It's one of those things that comes up periodically and spawns a discussion thread, but never really gets to a concrete proposal. The best I can find is this, which never even got submitted to the official PEP repository, but it's someone's attempt to make something that could potentially become one, so it's a start. https://github.com/DavidMertz/peps/blob/master/pep-9999.rst The trouble is, it's really REALLY hard to pin down useful semantics for deferred evaluation. We already have lambda functions, which cover a lot of situations, leaving a lot of uncertainty as to what's being handled by this new proposal - and since no proposal ever truly comes from a single person, that results in a certain amount of chaos. ChrisA
Thank you. I meant “superset of 671, not 505”… One question: def bar(a => None); return foo(a) def foo(a => object()): return a How would I force foo’s default from bar’s call? Would something like this work? def foo(a => object() if a is None else a): return a
On 18 Jul 2023, at 09:45, Chris Angelico <rosuav@gmail.com> wrote:
On Tue, 18 Jul 2023 at 16:25, Dom Grigonis <dom.grigonis@gmail.com> wrote:
Yes, thank you, this would definitely be nice to have.
Although, "A generic system for deferred evaluation has been proposed at times“ sound better if it was a superset of PEP505. Could you refer me to any resources about such considered system?
Hrm, you'd probably have to scour the archives. It's one of those things that comes up periodically and spawns a discussion thread, but never really gets to a concrete proposal. The best I can find is this, which never even got submitted to the official PEP repository, but it's someone's attempt to make something that could potentially become one, so it's a start.
https://github.com/DavidMertz/peps/blob/master/pep-9999.rst
The trouble is, it's really REALLY hard to pin down useful semantics for deferred evaluation. We already have lambda functions, which cover a lot of situations, leaving a lot of uncertainty as to what's being handled by this new proposal - and since no proposal ever truly comes from a single person, that results in a certain amount of chaos.
ChrisA
On Tue, 18 Jul 2023 at 19:02, Dom Grigonis <dom.grigonis@gmail.com> wrote:
Thank you.
I meant “superset of 671, not 505”…
One question:
def bar(a => None); return foo(a)
def foo(a => object()): return a
How would I force foo’s default from bar’s call?
That's a known-hard problem. The best way is probably to use *a,**kw and only pass the args you get, but that doesn't always work.
Would something like this work?
def foo(a => object() if a is None else a): return a
Yyyyyyes, but now you're defining that a could be None, so you may as well go with the classic idiom: def foo(a=None): if a is None: a = object() The point of default argument expressions is that you DON'T need to accept a fake default. ChrisA
Coming back to deferred evaluation, https://peps.python.org/pep-0671/ <https://peps.python.org/pep-0671/> These 2 aren’t really orthogonal in functionality. Maybe in implementation. But PEP671 is a certain subset of deferred evaluation as it can achieve the same with 1 extra line at the start of the function’s body. ------------------------------ Most importantly: If deferred evaluation had a CONCISE keyword/operator, it would actually solve my (and several other) requests/proposals. def ifelse(cond, if_true, if_false): return if_true if cond else if_false IF = ifelse def __init__(self, a=None, b=None): self.a = ifelse(a is not None, a, ?Foo()) self.b = IF(b is not None, b, `Bar()`) hopefully it would not be `later`... This way users could define their own constructs via callables & control order, evaluation and brevity to their liking. ------------------------------ https://peps.python.org/pep-0463/ <https://peps.python.org/pep-0463/> could also be achieved with a function. def trye(expr, err, default): try: return expr except err: return default value = trye(`dct[key]`, KeyError, 'No Value') ------------------------------ https://peps.python.org/pep-0505/ <https://peps.python.org/pep-0505/> def naw(a, b): if a is not None: return a else: return b a = None naw(a, `expr()`) # OR Infix operator: a |naw| `expr()` It starts to seem that it would solve all of the things I was looking at to a satisfactory degree (given a concise keyword obviously...). ------------------------------ With certain additions, could even break & continue... from statements import Break, Continue def ifelsebc(cond, val, else_break=True): if cond: return val elif else_break: return `Break(0)` else: return `Continue(0)` a = 0 while True: a += ifelsebc(a < 5, 1, else_break=True) print(a) # 5 The issue with lambda is that it has to be handled differently, or code has to check for its possibility, while deferred evaluation integrates seamlessly into already existing code. IMO, it would be an excellent addition. And all this would come as a side effect, rather than main intent (which is dask.delay functionality if I understood correctly). How likely you think is it going to happen? Given PEP number it doesn’t sound very promising...
On 18 Jul 2023, at 09:45, Chris Angelico <rosuav@gmail.com> wrote:
On Tue, 18 Jul 2023 at 16:25, Dom Grigonis <dom.grigonis@gmail.com> wrote:
Yes, thank you, this would definitely be nice to have.
Although, "A generic system for deferred evaluation has been proposed at times“ sound better if it was a superset of PEP505. Could you refer me to any resources about such considered system?
Hrm, you'd probably have to scour the archives. It's one of those things that comes up periodically and spawns a discussion thread, but never really gets to a concrete proposal. The best I can find is this, which never even got submitted to the official PEP repository, but it's someone's attempt to make something that could potentially become one, so it's a start.
https://github.com/DavidMertz/peps/blob/master/pep-9999.rst
The trouble is, it's really REALLY hard to pin down useful semantics for deferred evaluation. We already have lambda functions, which cover a lot of situations, leaving a lot of uncertainty as to what's being handled by this new proposal - and since no proposal ever truly comes from a single person, that results in a certain amount of chaos.
ChrisA
On Wed, 19 Jul 2023 at 11:51, Dom Grigonis <dom.grigonis@gmail.com> wrote:
Coming back to deferred evaluation,
https://peps.python.org/pep-0671/ These 2 aren’t really orthogonal in functionality. Maybe in implementation. But PEP671 is a certain subset of deferred evaluation as it can achieve the same with 1 extra line at the start of the function’s body.
No, it's not a subset of deferred evaluation, as has been stated clearly in the PEP and discussed many times in the past. Deferred evaluation is HARD. It's easy to handwave everything and pretend that it magically gets evaluated at the exact right time, but how do you actually define that? What are the scoping rules? Does it create a closure? Try creating an actual concrete specification and you may find out why it hasn't been implemented yet. ChrisA
On 7/18/23 12:03 AM, Dom Grigonis wrote:
Ok, thanks. I think what I am aiming at is that there is a pool of suggestions and PEPs that are pointing towards very similar direction and I find myself often wandering in the same space, just trying to figure out what it exactly is.
It sometimes feels more verbose than it could be for what it is in the context of how simple python is to use in general.
I am fully well aware that current if-else expression is not going anywhere. Chances that another expression is introduced, which does exactly the same thing are close to none.
So I am just gauging if it is a matter of conciseness of existing expressions or absence of something that could be there. Conditional if-else is just a place where I got to naturally.
Got some useful references to PEPs, python history and opinions. Maybe it will become more clear in the future or maybe something new is already being worked that is going to fill the gap which I am not aware of.
I haven’t even started any proposal myself, I was just following e-mail requests and rejected PEPs that were mentioned here. Combined it with my own experience and this is where I got to.
Currently seems like it’s a dead end. Decision’s have been made, opinions taken into account, but I still have to write either:
a) awkward 1-liner self.value= valueif valueis not None else DefaultClass() b) 3 nicely readable lines with 1 unnecessary assignment. self.value= value if valueis None: self.value= DefaultClass()
or, changing around: if value is None: value = DefaultClass() self.value = value since the assignment is fundamental to the operation of the function, that is adding 2 lines to implement an optional default, which isn't that much to implement the feature. it could be simplified to one line as if value is None: value = DefaultClass() (I think this is legal but against PEP8)
c) 4 lines, no unnecessary assignments with excellent readability. if valueis None: self.value= DefaultClass() else: self.value= value
The issue with b) and c) is that if I use those ones, my constructors become unbearably long and finally lead to the point where development becomes awkward. I would think that for what it does, it shouldn’t be more than 1 line. Max - 2. But a) is somewhat awkward. All (well not all, just several things) taken into account I ended up at inconvenience of `ifelse` expression, which would make a) my natural choice in this case. I am not even suggesting to introduce analogous `ifelse` with different syntax, just trying to get some ideas, references, opinions or alternatives that I don’t know about. -
Richard Damon
participants (5)
-
Chris Angelico
-
Dom Grigonis
-
Greg Ewing
-
Laurent Lyaudet
-
Richard Damon