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 06:43, Dom Grigonis <dom.grigonis@gmail.com> wrote:
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.
Your second example needs a "both are abhorrently unreadable" option. But if you've studied anything whatsoever about the history of the conditional expression in Python, you would know that a survey is actually pretty non-indicative here. We've already seen a much more rigorous survey than this, and the results were preserved for posterity. https://peps.python.org/pep-0308/#detailed-results-of-voting ChrisA
On Tue, Jul 18, 2023 at 07:09:54AM +1000, Chris Angelico <rosuav@gmail.com> wrote:
On Tue, 18 Jul 2023 at 06:43, Dom Grigonis <dom.grigonis@gmail.com> wrote: [skip]
Your second example needs a "both are abhorrently unreadable" option.
+1 [skip]
ChrisA
Oleg. -- Oleg Broytman https://phdru.name/ phd@phdru.name Programmers don't die, they just GOSUB without RETURN.
This ship has sailed and the ternary operator isn't going to change. Seriously, let it go. I forget the PEP, but this was well discussed long ago when the ternary was added. In general, Python prefers words to punctuation symbols for most of its constructs. So the decision was consistent with that. I do believe that such a choice is friendlier for people learning a first programming language, since it resembles English prose. While I like the C-style operator as well, I think the Python version does the right thing by emphasizing the DEFAULT by putting it first, and leaving the predicate and fallback until later in the expression (right for Pythonic code, not right for other languages necessarily). Either way, the question is moot. On Mon, Jul 17, 2023 at 4:42 PM Dom Grigonis <dom.grigonis@gmail.com> wrote:
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
Would be interesting to see if my preference is an outlier or not really.
Kind regards, D. Grigonis
_______________________________________________ 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/NZVLR5... Code of Conduct: http://python.org/psf/codeofconduct/
-- The dead increasingly dominate and strangle both the living and the not-yet born. Vampiric capital and undead corporate persons abuse the lives and control the thoughts of homo faber. Ideas, once born, become abortifacients against new conceptions.
I found the original discussion about the ternary addition, FWIW: https://mail.python.org/pipermail/python-dev/2005-September/056846.html. I don't see myself participating in the discussion (maybe it's in a different thread), but I'm delighted to remember that the message Guido posted a couple hours earlier than that announcement was about a talk I gave back then. On Mon, Jul 17, 2023 at 5:23 PM David Mertz, Ph.D. <david.mertz@gmail.com> wrote:
This ship has sailed and the ternary operator isn't going to change. Seriously, let it go.
I forget the PEP, but this was well discussed long ago when the ternary was added. In general, Python prefers words to punctuation symbols for most of its constructs. So the decision was consistent with that. I do believe that such a choice is friendlier for people learning a first programming language, since it resembles English prose. While I like the C-style operator as well, I think the Python version does the right thing by emphasizing the DEFAULT by putting it first, and leaving the predicate and fallback until later in the expression (right for Pythonic code, not right for other languages necessarily).
Either way, the question is moot.
On Mon, Jul 17, 2023 at 4:42 PM Dom Grigonis <dom.grigonis@gmail.com> wrote:
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
Would be interesting to see if my preference is an outlier or not really.
Kind regards, D. Grigonis
_______________________________________________ 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/NZVLR5... Code of Conduct: http://python.org/psf/codeofconduct/
-- The dead increasingly dominate and strangle both the living and the not-yet born. Vampiric capital and undead corporate persons abuse the lives and control the thoughts of homo faber. Ideas, once born, become abortifacients against new conceptions.
-- The dead increasingly dominate and strangle both the living and the not-yet born. Vampiric capital and undead corporate persons abuse the lives and control the thoughts of homo faber. Ideas, once born, become abortifacients against new conceptions.
A bit disappointing, but very much expected. I just though a bit of effort is worth even for 0.1% probability of success. At least from where I stand, such change would make a fairly big impact on the things I do, given my expected relationship with python. I haven’t studied much of a history of python and I know how much I do not know. I always let go when there is a conviction it is a right thing to do. :) Thank you for your reply. PEPs that get referred to in this group are always informative to me. Maybe I will spend some time going through PEPs to get a bit more familiar.
On 18 Jul 2023, at 00:23, David Mertz, Ph.D. <david.mertz@gmail.com> wrote:
This ship has sailed and the ternary operator isn't going to change. Seriously, let it go.
I forget the PEP, but this was well discussed long ago when the ternary was added. In general, Python prefers words to punctuation symbols for most of its constructs. So the decision was consistent with that. I do believe that such a choice is friendlier for people learning a first programming language, since it resembles English prose. While I like the C-style operator as well, I think the Python version does the right thing by emphasizing the DEFAULT by putting it first, and leaving the predicate and fallback until later in the expression (right for Pythonic code, not right for other languages necessarily).
Either way, the question is moot.
On Mon, Jul 17, 2023 at 4:42 PM Dom Grigonis <dom.grigonis@gmail.com <mailto:dom.grigonis@gmail.com>> wrote: 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
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org <mailto:python-ideas@python.org> To unsubscribe send an email to python-ideas-leave@python.org <mailto:python-ideas-leave@python.org> https://mail.python.org/mailman3/lists/python-ideas.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/NZVLR5... <https://mail.python.org/archives/list/python-ideas@python.org/message/NZVLR56BFMBJXE6GN2GWRXIG6ZVAAWZZ/> Code of Conduct: http://python.org/psf/codeofconduct/ <http://python.org/psf/codeofconduct/>
-- The dead increasingly dominate and strangle both the living and the not-yet born. Vampiric capital and undead corporate persons abuse the lives and control the thoughts of homo faber. Ideas, once born, become abortifacients against new conceptions.
David Mertz, Ph.D. writes:
I think the Python version does the right thing by emphasizing the DEFAULT by putting it first, and leaving the predicate and fallback until later in the expression (right for Pythonic code, not right for other languages necessarily).
Aside: I think that's true for Pythonic scripting, but in general I think you're just as likely to find that it's a genuine choice, and that the condition is as interesting as either choice. Variation on the theme of conditional expression: I'd often like to write var = computed() if cond() else break or var = computed() if cond() else continue I wonder if that syntax has legs, or if it's too cute to stand.
Maybe could be a part of https://peps.python.org/pep-0463/ <https://peps.python.org/pep-0463/> Maybe if it was more expressive, e.g. covering the case such as you suggesting, it would go through? Also, I still don't see why changing analogous statement order when making 1-line expressions is a good idea. E.g. there was a statement: # Statement try: expression1 except Exception: expression2 except Exception: expression1 el<if cond1: expression3 elif cond2: expression4 else: expression5> finally: expression6 It’s analogous expression then could be: val = try expr1() except Exception ? expr2() el<if cond1() ? expr3() else expr4()> finally expr5() Simple if-else statement would be everything in between <> in both statement and expression. Functional, consistent, expressive, in line with what is already there. Both “continue” and “break" would also be used in expressions same place as the statement. Maybe something else instead of “?”, but it doesn’t matter much to me, “?” would be just fine. This would also partly cover my “rant” about C’s conditional expression. I.e. The order. Which probably has more weight in my aversion than it’s verbosity. * Now argument that expressions read more naturally in this order raises a question "Why then isn’t it the same in statements?”. * And argument that it’s easier for someone to learn without programming background also fails as even they would probably prefer “consistency" as opposed to "inconsistency, but 1 part reads like english." I personally find it easier to learn when I understand and I understand when things make sense and follow patterns. Can it be that too much of this is being sacrificed for the sake of factors which are not as important?
On 18 Jul 2023, at 09:08, Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
David Mertz, Ph.D. writes:
I think the Python version does the right thing by emphasizing the DEFAULT by putting it first, and leaving the predicate and fallback until later in the expression (right for Pythonic code, not right for other languages necessarily).
Aside: I think that's true for Pythonic scripting, but in general I think you're just as likely to find that it's a genuine choice, and that the condition is as interesting as either choice.
Variation on the theme of conditional expression: I'd often like to write
var = computed() if cond() else break
or
var = computed() if cond() else continue
I wonder if that syntax has legs, or if it's too cute to stand.
On Fri, 21 Jul 2023 at 05:53, Random832 <random832@fastmail.com> wrote:
On Mon, Jul 17, 2023, at 16:41, Dom Grigonis wrote:
Would be interesting to see if my preference is an outlier or not really.
I think this is a false dichotomy. We should consider VB-like conditional expressions if(condition, when_true, when_false) as well.
Why? That sort of expression would be syntactically a function call, which you can already create, but which would eagerly evaluate both its arguments. The entire value of an actual conditional expression is that it WON'T evaluate the expression it isn't using. ChrisA
That is where I got to really. Ability to construct one’s own expressions, where evaluation can be controlled. And found out that deferred evaluation is what would potentially provide exactly what is needed for this. Making use of ‘function’ protocol seems appropriate as I don’t think inventing any extensive syntax is justified. from lazy_object_proxy import Proxy value = Proxy(lambda: expr()) # If this could be written in a more concise form. e.g.: value = `expr()` # then it would be worthwhile constructing and making use of VB-like expressions def IF(condition, when_true, when_false): if condition: return when_true else: return when_false def expr1(): print('__expr1__') return 1 def expr2(): print('__expr2__') return 2 result = IF(True, `expr1()`, `expr2()`) # Expressions would only be evaluated when certain usage takes place # This works fairly nicely, but inconvenience of it is a dealbreaker (to be used for such cases) result = IF(True, Proxy(lambda: expr1()), Proxy(lambda: expr2())) # Not yet evaluated print(result + 1) # Now it is Also, can't find a way to ONLY force evaluation without any additional operations in this specific library. A simple callable which evaluates if unevaluated & returns would do. Then: def IF(condition, when_true, when_false): if condition: return ensure_eval(when_true) else: return ensure_eval(when_false) Controls evaluation if deferred objects are provided, but can also be used with `normal` values.
On 20 Jul 2023, at 22:51, Random832 <random832@fastmail.com> wrote:
On Mon, Jul 17, 2023, at 16:41, Dom Grigonis wrote:
Would be interesting to see if my preference is an outlier or not really.
I think this is a false dichotomy. We should consider VB-like conditional expressions if(condition, when_true, when_false) as well. _______________________________________________ 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/FZBHN6... Code of Conduct: http://python.org/psf/codeofconduct/
On Fri, 21 Jul 2023 at 11:08, Dom Grigonis <dom.grigonis@gmail.com> wrote:
Also, can't find a way to ONLY force evaluation without any additional operations in this specific library. A simple callable which evaluates if unevaluated & returns would do. Then:
def IF(condition, when_true, when_false): if condition: return ensure_eval(when_true) else: return ensure_eval(when_false)
Controls evaluation if deferred objects are provided, but can also be used with `normal` values.
Let's tackle just this one part for a moment. What does "ensure_eval" do? Evaluate a proxy object but not evaluate anything else? That seems simple, but might very well be straight-up wrong. Consider: def test_proxy(x): x_ = Proxy(x) y = ensure_eval(x_) y_ = ensure_eval(y) assert x is y assert x is y_ This should always succeed, right? Well, what if x is itself a Proxy object? How does it know not to reevaluate it? ChrisA
This is very much implementation dependent. And I do not have a big opinion here as I certainly haven’t spent enough time to have one. I am just considering functionality from user’s perspective for the time being.
Let's tackle just this one part for a moment. What does "ensure_eval" do? Evaluate a proxy object but not evaluate anything else?
In case of the library I used, it would look something like: def ensure_eval(x): if isisnstance(x, Proxy) and x.unevaulated: x.evaluate() return x
This should always succeed, right? Well, what if x is itself a Proxy object? How does it know not to reevaluate it?
Not necessarily. I mean, yes, but only if deferred evaluation is done by actually replacing value in the namespace dictionary. In case of this example, where this specific package is used, it is not so and is not intended to be so. When operation is performed, the value is evaluated and returned, but it remains proxy object. So if lazy is nested, the whole nesting is evaluated on first operation which needs its value. I see this one as “decision to be made” as opposed to “reason why it’s not working”. I am not sure about the “right” approach here. Actually replacing deferred object with a value does sound invasive, although given there was a way to do it elegantly and without loss in performance, it seems to be more robust and eliminates maintenance of proxy object. So the big question is, which of the 2 approaches to take: 1) Implementing a robust proxy object. Less depth more breadth - ensuring proxy works with all objects / coming up with protocols, which have to be implemented for non-standard types to be compatible. In this case both of assertions will and should fail, although `assert y is y_` will always pass. Example from library: obj = Proxy(lambda: 1) obj2 = Proxy(lambda: obj) obj is obj2 # False print(obj == obj2) # True 2) Replacing deferred evaluation with it’s value. in this case, a fair bit of low level decisions such as the one you indicated would have to be made, a lot of deep strings to pull In this case, it very much depends how “is”, “type” and other `things` behave with deferred objects. So if `x` is a proxy, and ‘is’ treats proxy object and not it’s value (which is reasonable), then assertions will and should fail. However, unraveling the whole stack on first evaluation does simplify things a bit.Then ` y_ = ensure_eval(y)` in your example is a redundant line. In practice, if deferred evaluation is used, one would need to: `assert ensure_eval(x) is ensure_eval(y)`. Also, looking at deferred eval RST doc, the suggested mechanics are that expression is evaluated if “later” is not re-called. So in theory, it might be reasonable to have `x = later expr() <equiv> x = later later later expr()`. Instead of evaluating the whole stack, just not allowing it to grow in the first place. Then builtin `ensure_eval` is then straight forward single operation at C level, which would mostly be used on low level checks, such as asserts in your examples. It could even have its syntax instead of builtin function, given there are only 2 entry points (definition of deferred & ensuring it’s evaluation). E.g. def expr(): print('Evaluating') return 1 a = `expr()` b = `a` # carry over lazy, but it's a new object at C level assert a is b # False assert !a is !b # True assert a is b # True
On 21 Jul 2023, at 08:46, Chris Angelico <rosuav@gmail.com> wrote:
On Fri, 21 Jul 2023 at 11:08, Dom Grigonis <dom.grigonis@gmail.com> wrote:
Also, can't find a way to ONLY force evaluation without any additional operations in this specific library. A simple callable which evaluates if unevaluated & returns would do. Then:
def IF(condition, when_true, when_false): if condition: return ensure_eval(when_true) else: return ensure_eval(when_false)
Controls evaluation if deferred objects are provided, but can also be used with `normal` values.
Let's tackle just this one part for a moment. What does "ensure_eval" do? Evaluate a proxy object but not evaluate anything else? That seems simple, but might very well be straight-up wrong. Consider:
def test_proxy(x): x_ = Proxy(x) y = ensure_eval(x_) y_ = ensure_eval(y) assert x is y assert x is y_
This should always succeed, right? Well, what if x is itself a Proxy object? How does it know not to reevaluate it?
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/GTCRUP... Code of Conduct: http://python.org/psf/codeofconduct/
Having said that, What about a mid-ground approach? Simply have a `deferred` type, which only gets evaluated if it is explicitly asked for. It builds a graph in the same way as dask, but it does not act as a proxy, but rather evaluates if explicitly asked. From technical perspective, it would be the same as dask - non-invasive so would have minimal to none impact on existing code. One difference would be that the object would not manage operations, but rather leave it as expression at lower level of python. From user’s perspective it would be similar to lambdas or dask, except with convenient syntax and seamless integration to existing code. E.g. a = `1` print(type(a)) # <Deferred> print(type(a.graph())) # <Graph> print(a.eval()) # 1 a print(type(a)) # <Deferred> print(!a) # 1 print(type(a)) # <Deferred> b = !a print(type(b)) # int print(!1) # 1 c = `a + 1` d = `c + 2` e = `c + d` # simply builds graph print(eval(e)) # 7 (this is only used if one is sure that it is <Deferred>) print(!e) # 7 (this untangles if <Deferred> or just pass through for anything else) So no magic really, pretty straight forward. Benefits for dask-like applications is to have a lower level & more performant deferred object with API to customise evaluation. For such applications evaluation would be done via `eval(obj)` or `obj.eval()` as it strictly has to be <Deferred> object and should fail if it’s not. While convenient builtins would be useful for expression building, Infix operators and similar applications. In this case it does act very similarly as lambda, but solves a few of lambda’s inconveniences: 1) if using lambda/callables for this purpose, then can not use them as values. Same argument as for async/await vs using yield. Simply another layer of depth is needed to remove ambiguity. 2) Syntax is too cumbersome - something properly concise IMO should be available for it to be convenient. 3) More performant operations than e.g. `isinstance(value, Callable)`. Function without arguments could be converted to <Deferred> via decorator or multiline expression could be defined via ``` a = 1 b = a + 1 b ``` ——————————————————— Expressions would naturally be evaluated at the scope of their definition. Nothing new. ——————————————————— Regarding Break & Continue: Can still be achieved: from statements import Break def ifelse(cond, if_true, if_false): if cond: return !if_true else: return !if_false a = 0 while True: # This would require to be mindful about conditional values a += ifelse(a < 5, `expr()`, False) or Break(return_value=0) # or for it to be “perfect", PEP505 is needed a += ifelse(a < 5, `expr()`, None) ?? Break(return_value=0) However, it could be done differently as well. If `Break()` takes effect in the scope where it is evaluated. Then: from statements import Break def add_or_break(cond, if_true, break_return): if cond: return if_true else: return `Break(return_value=break_return)` a = 0 while True: a += !(add_or_break(a < 5, `expr()`, break_return=0)) ——————————————————— So these would potentially provide a fairly flexible toolkit for expression building and seemingly covers all the cases that I was looking at including reasonable route to achieve https://peps.python.org/pep-0463/ <https://peps.python.org/pep-0463/>. And it might be a feasible approach for deferred evaluation. Just not sure if this covers the needs that it is aiming to fulfil. DG
On 21 Jul 2023, at 10:31, Dom Grigonis <dom.grigonis@gmail.com> wrote:
This is very much implementation dependent. And I do not have a big opinion here as I certainly haven’t spent enough time to have one. I am just considering functionality from user’s perspective for the time being.
Let's tackle just this one part for a moment. What does "ensure_eval" do? Evaluate a proxy object but not evaluate anything else?
In case of the library I used, it would look something like:
def ensure_eval(x): if isisnstance(x, Proxy) and x.unevaulated: x.evaluate() return x
This should always succeed, right? Well, what if x is itself a Proxy object? How does it know not to reevaluate it?
Not necessarily. I mean, yes, but only if deferred evaluation is done by actually replacing value in the namespace dictionary. In case of this example, where this specific package is used, it is not so and is not intended to be so.
When operation is performed, the value is evaluated and returned, but it remains proxy object. So if lazy is nested, the whole nesting is evaluated on first operation which needs its value.
I see this one as “decision to be made” as opposed to “reason why it’s not working”.
I am not sure about the “right” approach here. Actually replacing deferred object with a value does sound invasive, although given there was a way to do it elegantly and without loss in performance, it seems to be more robust and eliminates maintenance of proxy object.
So the big question is, which of the 2 approaches to take: 1) Implementing a robust proxy object. Less depth more breadth - ensuring proxy works with all objects / coming up with protocols, which have to be implemented for non-standard types to be compatible. In this case both of assertions will and should fail, although `assert y is y_` will always pass.
Example from library: obj = Proxy(lambda: 1) obj2 = Proxy(lambda: obj) obj is obj2 # False print(obj == obj2) # True
2) Replacing deferred evaluation with it’s value. in this case, a fair bit of low level decisions such as the one you indicated would have to be made, a lot of deep strings to pull In this case, it very much depends how “is”, “type” and other `things` behave with deferred objects. So if `x` is a proxy, and ‘is’ treats proxy object and not it’s value (which is reasonable), then assertions will and should fail. However, unraveling the whole stack on first evaluation does simplify things a bit.Then ` y_ = ensure_eval(y)` in your example is a redundant line. In practice, if deferred evaluation is used, one would need to: `assert ensure_eval(x) is ensure_eval(y)`. Also, looking at deferred eval RST doc, the suggested mechanics are that expression is evaluated if “later” is not re-called. So in theory, it might be reasonable to have `x = later expr() <equiv> x = later later later expr()`. Instead of evaluating the whole stack, just not allowing it to grow in the first place. Then builtin `ensure_eval` is then straight forward single operation at C level, which would mostly be used on low level checks, such as asserts in your examples. It could even have its syntax instead of builtin function, given there are only 2 entry points (definition of deferred & ensuring it’s evaluation). E.g. def expr(): print('Evaluating') return 1
a = `expr()` b = `a` # carry over lazy, but it's a new object at C level assert a is b # False assert !a is !b # True assert a is b # True
On 21 Jul 2023, at 08:46, Chris Angelico <rosuav@gmail.com <mailto:rosuav@gmail.com>> wrote:
On Fri, 21 Jul 2023 at 11:08, Dom Grigonis <dom.grigonis@gmail.com <mailto:dom.grigonis@gmail.com>> wrote:
Also, can't find a way to ONLY force evaluation without any additional operations in this specific library. A simple callable which evaluates if unevaluated & returns would do. Then:
def IF(condition, when_true, when_false): if condition: return ensure_eval(when_true) else: return ensure_eval(when_false)
Controls evaluation if deferred objects are provided, but can also be used with `normal` values.
Let's tackle just this one part for a moment. What does "ensure_eval" do? Evaluate a proxy object but not evaluate anything else? That seems simple, but might very well be straight-up wrong. Consider:
def test_proxy(x): x_ = Proxy(x) y = ensure_eval(x_) y_ = ensure_eval(y) assert x is y assert x is y_
This should always succeed, right? Well, what if x is itself a Proxy object? How does it know not to reevaluate it?
ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org <mailto:python-ideas@python.org> To unsubscribe send an email to python-ideas-leave@python.org <mailto:python-ideas-leave@python.org> https://mail.python.org/mailman3/lists/python-ideas.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/GTCRUP... Code of Conduct: http://python.org/psf/codeofconduct/
On Fri, 21 Jul 2023 at 19:15, Dom Grigonis <dom.grigonis@gmail.com> wrote:
However, it could be done differently as well. If `Break()` takes effect in the scope where it is evaluated. Then:
You say that as if it's easy. How would this work? How do you have a function that, when called, causes the current loop to be broken out of? ChrisA
Did not mean that it is easy, but it seems achievable and although a deep dig might be needed, my gut feeling is that it is possible to achieve this fairly elegantly. I might be wrong ofc. However, this seems orthogonal to everything else I wrote. Just added it for the sake of completeness, this could be a nice one to have further along the lines, given def-eval was implemented. Then complete statements would be possible via expressions with full functionality.
On 21 Jul 2023, at 12:19, Chris Angelico <rosuav@gmail.com> wrote:
On Fri, 21 Jul 2023 at 19:15, Dom Grigonis <dom.grigonis@gmail.com> wrote:
However, it could be done differently as well. If `Break()` takes effect in the scope where it is evaluated. Then:
You say that as if it's easy. How would this work? How do you have a function that, when called, causes the current loop to be broken out of?
ChrisA
On Fri, 21 Jul 2023 at 19:58, Dom Grigonis <dom.grigonis@gmail.com> wrote:
Did not mean that it is easy, but it seems achievable and although a deep dig might be needed, my gut feeling is that it is possible to achieve this fairly elegantly. I might be wrong ofc.
Start on that deep dig, then, and figure out what the implications are. Remember, anyone can do this: func = Break and now func() has to behave as a break statement. Good luck. ChrisA
When can we expect the results of your survey? (I responded to it.) Best wishes Rob Cliffe On 17/07/2023 21:41, Dom Grigonis wrote:
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
Would be interesting to see if my preference is an outlier or not really.
Kind regards, D. Grigonis
_______________________________________________ Python-ideas mailing list --python-ideas@python.org To unsubscribe send an email topython-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived athttps://mail.python.org/archives/list/python-ideas@python.org/message/NZVLR5... Code of Conduct:http://python.org/psf/codeofconduct/
Thank you for reminding Rob. Results are not surprising. Although 10 years ago people preferred C-style, by this time everyone is used to python’s expression. By this time, after having discussions, I myself, am not a proponent of such change. It was more about possibility of having 2 conditional expressions, not changing it. It was just a part of my more general investigation. My current position is that “deferred evaluation” (if implemented with brief syntax) will cover many (sometimes seemingly unrelated) cases as a side effect of its main intent. Ok, results. Not many respondents. 48 in total. Average 24 per question. (Not sure how that happened.) 1. Which conditional expression is more readable? 83%: var = foo if condition else bar 17%: var = condition ? foo : bar 2. Which conditional expression is more readable? 84%: var = (foo if foo is not None else default2) if condition else (bar if bar is not None else default2) 16%: var = condition ? (foo is not None ? foo : default1) : (bar is not None ? bar: default2) 3. Would you use more conditional expression statements if it was more like in C? 12%: yes 88%: no Comments: 1. They are fine the way they are. 2. They're fine for occasional use, as your second example abundantly shows, nested conditionals are an abomination in the sight of beasts and men. 3. The C syntax is undecipherable gobbledegook to beginners or people coming from other languages without that same syntax. It is the opposite of Python's ideal of "executable pseudocode". The Python syntax is easily understandable to anyone who knows English as it follows English syntax: "What are you doing tonight?" "I'm going to the movies, if I manage to leave work on time, otherwise I'll just stay home.” * Is the english sentence “If I manage to leave work on time, I’m going to the movies, otherwise, I’ll just stay home” incorrect? 4. lol, I would never use that nested conditional expression. I'd definitely break it out into an if-else statement that had the conditional expressions. (I also break out nested list comprehension a into a for loop for readability in the rare cases I have them.) 5. Don't change them now! (this was hashed out 20 years ago!) * It was more about adding an alternative, not changing it. 6. Python conditional expressions are English, or very nearly. C ones, using a question mark which could mean anything, are obscure (unless perhaps you are very very familiar with them). 7. I do not 8. they won't change 9. Python has a syntax for conditional expressions. Learn it, if you want to use Python. No need to create multiple syntaxes for the same thing. * Hello Chris A? :) 10. Conditional expressions are always confusing 11. Syntax highlighting matters and adds to the inherent readability of Python's ansatz. Thank you all for taking your time in these discussions and filling in this quick survey. This has helped me getting answers I was looking for. Hopefully, this wasn’t a waste of time from your perspectives either. —Nothing ever dies, just enters the state of deferred evaluation— Dg
On 5 Aug 2023, at 09:22, Rob Cliffe <rob.cliffe@btinternet.com> wrote:
When can we expect the results of your survey? (I responded to it.) Best wishes Rob Cliffe
On 17/07/2023 21:41, Dom Grigonis wrote:
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
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org <mailto:python-ideas@python.org> To unsubscribe send an email to python-ideas-leave@python.org <mailto:python-ideas-leave@python.org> https://mail.python.org/mailman3/lists/python-ideas.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/NZVLR5... <https://mail.python.org/archives/list/python-ideas@python.org/message/NZVLR56BFMBJXE6GN2GWRXIG6ZVAAWZZ/> Code of Conduct: http://python.org/psf/codeofconduct/ <http://python.org/psf/codeofconduct/>
Ok.
On 5 Aug 2023, at 16:02, Chris Angelico <rosuav@gmail.com> wrote:
On Sat, 5 Aug 2023 at 22:49, Dom Grigonis <dom.grigonis@gmail.com> wrote:
9. Python has a syntax for conditional expressions. Learn it, if you want to use Python. No need to create multiple syntaxes for the same thing. * Hello Chris A? :)
Nope.
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/6GDLIO... Code of Conduct: http://python.org/psf/codeofconduct/
On Sat, 5 Aug 2023 at 22:49, Dom Grigonis <dom.grigonis@gmail.com> wrote:
3. The Python syntax is easily understandable to anyone who knows English as it follows English syntax: "What are you doing tonight?" "I'm going to the movies, if I manage to leave work on time, otherwise I'll just stay home.” * Is the english sentence “If I manage to leave work on time, I’m going to the movies, otherwise, I’ll just stay home” incorrect?
This is a VERY common objection to Python's syntax. No, the English sentence you provide isn't wrong, and the "follows English syntax" argument is not saying that C's way of laying it out is wrong. English happily supports both orders. But that's a relatively weak justification, since this is the same English that has a purple fruit called a "grape", and then a completely different fruit in a different family called a "grapefruit"; and where there's no well-accepted word for "the day after tomorrow", but after some incidents in Prague, came up with the glorious word "defenestration", which can also refer to shutting down your GUI and returning to terminal mode. So I would say this is only really of value as a rebuttal to "Python's conditional syntax makes no sense", by saying "yeah well, it's no worse than English". Which is kinda like saying "banging your head against a wall doesn't hurt **that** much, it's not as bad as maintaining a PHP web site.". ChrisA
participants (7)
-
Chris Angelico
-
David Mertz, Ph.D.
-
Dom Grigonis
-
Oleg Broytman
-
Random832
-
Rob Cliffe
-
Stephen J. Turnbull