What's the status of PEP 505: None-aware operators?

Hi Mark, it looks like the PEP is dormant for over two years now. I had multiple people ask me over the past few days about it though, so I wanted to ask if this is moving forward. I also cc python-dev to see if anybody here is strongly in favor or against this inclusion. If the idea itself is uncontroversial, I could likely find somebody interested in implementing it. If not for 3.7 then at least for 3.8. - Ł

Please, not for 3.7. I think it will be very difficult to get consensus about this, and I personally feel something like +/- zero about it -- sometimes I think it makes sense, sometimes I think we're jumping the shark here. On Tue, Nov 28, 2017 at 12:10 PM, Lukasz Langa <lukasz@langa.pl> wrote:
-- --Guido van Rossum (python.org/~guido)

On 29 November 2017 at 06:17, Guido van Rossum <guido@python.org> wrote:
I've marked all 3 of the related PEPs as Deferred until 3.8 at the earliest: https://github.com/python/peps/commit/181cc79af925e06a068733a1419b1760ac1a2d... PEP 505: None-aware operators PEP 532: A circuit breaking protocol and binary operators PEP 535: Rich comparison chaining I don't see any urgency to resolve any of them - the None-aware operators do make certain kinds of code (commonly found in JSON processing) easier to read and write, but such code is still fairly readable and writable today (it's just a bit verbose and boilerplate heavy), and the other two PEPs arise specifically from seeking to provide a common conceptual underpinning for the semantics of both the proposed None-aware operations and the existing short-circuiting logical operators. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

I also cc python-dev to see if anybody here is strongly in favor or against this inclusion.
Put me down for a strong -1. The proposal would occasionally save a few keystokes but comes at the expense of giving Python a more Perlish look and a more arcane feel. One of the things I like about Python is that I can walk non-programmers through the code and explain what it does. The examples in PEP 505 look like a step in the wrong direction. They don't "look like Python" and make me feel like I have to decrypt the code to figure-out what it does. timeout ?? local_timeout ?? global_timeout 'foo' in (None ?? ['foo', 'bar']) requested_quantity ?? default_quantity * price name?.strip()[4:].upper() user?.first_name.upper() Raymond

On Nov 28, 2017, at 15:31, Raymond Hettinger <raymond.hettinger@gmail.com> wrote:
Put me down for a strong -1. The proposal would occasionally save a few keystokes but comes at the expense of giving Python a more Perlish look and a more arcane feel.
I am also -1.
One of the things I like about Python is that I can walk non-programmers through the code and explain what it does. The examples in PEP 505 look like a step in the wrong direction. They don't "look like Python" and make me feel like I have to decrypt the code to figure-out what it does.
I had occasional to speak with someone very involved in Rust development. They have a process roughly similar to our PEPs. One of the things he told me, which I found very interesting and have been mulling over for PEPs is, they require a section in their specification discussion how any new feature will be taught, both to new Rust programmers and experienced ones. I love the emphasis on teachability. Sometimes I really miss that when considering some of the PEPs and the features they introduce (look how hard it is to teach asynchronous programming). Cheers, -Barry

On 28 November 2017 at 20:38, Barry Warsaw <barry@python.org> wrote:
-1 from me, too.
One of the things I like about Python is that I can walk non-programmers through the code and explain what it does. The examples in PEP 505 look like a step in the wrong direction. They don't "look like Python" and make me feel like I have to decrypt the code to figure-out what it does.
I had occasional to speak with someone very involved in Rust development. They have a process roughly similar to our PEPs. One of the things he told me, which I found very interesting and have been mulling over for PEPs is, they require a section in their specification discussion how any new feature will be taught, both to new Rust programmers and experienced ones. I love the emphasis on teachability. Sometimes I really miss that when considering some of the PEPs and the features they introduce (look how hard it is to teach asynchronous programming).
That's a really nice idea. I'd like to see Python adopt something similar (even just as a guideline on how to write a PEP). Paul

On Nov 28, 2017, at 15:59, Paul Moore <p.f.moore@gmail.com> wrote:
On 28 November 2017 at 20:38, Barry Warsaw <barry@python.org> wrote:

Not really related but the PEP says that arguments in Python are evaluated before the function (as a reason to reject the idea of None-aware function call) but this is not the case: >>> import dis >>> dis.dis(lambda : f()(g())) 1 0 LOAD_GLOBAL 0 (f) 3 CALL_FUNCTION 0 6 LOAD_GLOBAL 1 (g) 9 CALL_FUNCTION 0 12 CALL_FUNCTION 1 15 RETURN_VALUE Andrea On Wed, Nov 29, 2017 at 7:14 PM, Joao S. O. Bueno <jsbueno@python.org.br> wrote:

On Thu, Nov 30, 2017 at 2:48 AM, Andrea Griffini <agriff@tin.it> wrote:
I think you're missing something here, since it seems clear to me that indeed the arguments are evaluated prior to the function call. Maybe unrolling it would help? This is equivalent to the body of your lambda, and you can see that the argument is evaluated prior to the call which receives it.
>>> import dis
Call 'f()' with all of its arguments evaluated prior to the call (there are none, that's the '0' on the CALL_FUNCTION operator).
6 LOAD_GLOBAL 1 (g) 9 CALL_FUNCTION 0
Next, evaluate the arguments for the next function call. Call 'g()' with all of its arguments evaluated.
12 CALL_FUNCTION 1
Call the function that 'f()' returned with its argument ('g()') evaluated.

Eric Fahlgren wrote:
I think you're missing something here, since it seems clear to me that indeed the arguments are evaluated prior to the function call.
I think the OP may be confusing "evaluating the function" with "calling the function". If the function being called is determined by some computation, that computation may be performed before its arguments are evaluated (and is probably required to be, by the "left to right" rule). But the arguments will always be evaluated before the actual call happens. -- Greg

On Thu, Nov 30, 2017, at 17:26, Greg Ewing wrote:
Right, but if the function is evaluated before either of those things happen, then it can indeed short-circuit the argument evaluation. The OP isn't confusing anything; it's Eric who is confused. The quoted paragraph of the PEP clearly and unambiguously claims that the sequence is "arguments -> function -> call", meaning that something happens after the "function" stage [i.e. a None check] cannot short-circuit the "arguments" stage. But in fact the sequence is "function -> arguments -> call".

On Thu, Nov 30, 2017 at 11:54:39PM -0500, Random832 wrote:
I'm more confused than ever. You seem to be arguing that Python functions CAN short-circuit their arguments and avoid evaluating them. Is that the case? If not, then I fail to see the difference between "arguments -> function -> call" "function -> arguments -> call" In *both cases* the arguments are fully evaluated before the function is called, and so there is nothing the function can do to delay evaluating its arguments. If this is merely about when the name "function" is looked up, then I don't see why that's relevant to the PEP. What am I missing? -- Steve

On Fri, Dec 1, 2017 at 10:31 AM, Steven D'Aprano <steve@pearwood.info> wrote: the expression immediately to the left of the argument list) and/or the argument has side effects then the evaluation order will affect the outcome. Intuitively it seems more straightforward to compute the function first. If this expression were to raise an exception, of course, then the arguments would not then be evaluated. Or vice versa. It would be best of the specification matches current CPython bahviour.

On Fri, Dec 1, 2017, at 05:31, Steven D'Aprano wrote:
You're completely missing the context of the discussion, which was the supposed reason that a *new* function call operator, with the proposed syntax function?(args), that would short-circuit (based on the 'function' being None) could not be implemented. The whole thing doesn't make sense to me anyway, since a new operator could have its own sequence different from the existing one if necessary.

On Fri, Dec 01, 2017 at 08:24:05AM -0500, Random832 wrote:
Yes I am. That's why I asked.
Given that neither your post (which I replied to) nor the post you were replying to mentioned anything about function?() syntax, perhaps I might be forgiven for having no idea what you were talking about? The PEP only mentions function?() as a rejected idea, do I don't know why we're even talking about it. The PEP is deferred, with considerable opposition and luke-warm support, even the PEP author has said he's not going to push for it, and we're arguing about a pedantic point related to a part of the PEP which is rejected... :-) -- Steve

On 2 December 2017 at 12:01, Steven D'Aprano <steve@pearwood.info> wrote:
Nevertheless, I've fixed the rationale for that decision so folks don't get hung up on the mistake in the previously noted rationale: https://github.com/python/peps/commit/966dd426787e6de8ec6218955cec57f65086c5... Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

The PEP says that a None-aware function call operator (e.g. "f?(x, y)") would break the rule of python that arguments are evaluated before the function but this is not correct. In Python the function is evaluated before the arguments (but of course the CALL is made after the evaluation of the arguments). A None-aware function call operator ?(...) wouldn't break this order of evaluation rule: 1) evaluate the function, 2) only if it's not None evaluate arguments and make the call. In bytecode the None-aware function call would simply require a extra "JNONE" to the end... ... evaluate the function ... JNONE skip ... evaluate arguments ... CALL n skip: Note that I'm not saying this would be a good thing, just that the reason the PEP uses to dismiss this option is actually wrong because Python doesn't work the way the PEP says it does. Andrea On Fri, Dec 1, 2017 at 11:31 AM, Steven D'Aprano <steve@pearwood.info> wrote:

On 29 November 2017 at 07:15, Mark Haase <mehaase@gmail.com> wrote:
We should probably set the state of both this and the related circuit breaking protocol PEPs to Deferred so folks know neither of us is actually working on them. While I still think there's merit to the idea of making it easier to write concise data cleanup pipelines in Python, I find the argument "The currently proposed spelling doesn't even come close to reading like executable pseudo code" to be a compelling one. I think a big part of the problem is that these kinds of data cleanup operations don't even have a good *vocabulary* around them yet, so nobody actually knows how to write them as pseudo code in the first place - we only know how to express them in particular programming languages. Trying to come up with pseudo code for the example cases Raymond mentioned: timeout if defined, else local_timeout if defined, else global_timeout price * (requested_quantity if defined, else default_quantity) name if not defined, else name.strip()[4:].upper() user if not defined, else name.first_name.upper() And that's not actually that different to their current spellings in Python: timeout if timeout is not None else local_timeout if local_timeout is not None, else global_timeout price * (requested_quantity if requested_quantity is not None else default_quantity) name if name is None else name.strip()[4:].upper() user if user is None else name.first_name.upper() One key aspect that Python does miss relative to the pseudocode versions is that we don't actually have a term for "expr is not None". "def" is used specifically for functions, so "defined" isn't reference right. References to "None" are bound like anything else, so "bound" isn't right. "exists" probably comes closest (hence the title of the withdrawn PEP 531). That said, if we did decide to allow "def" in a conditional expression to mean "defined" in the "lhs is not None" sense, it would look like: timeout if def else local_timeout if def else global_timeout price * (requested_quantity if def else default_quantity) name if not def else name.strip()[4:].upper() user if not def else user.first_name.upper() Cheers, Nick. P.S. Compared to this, our last symbolic feature addition (matrix multiplication), was a relatively straightforward transcription of "⋅" to "@", just as regular multiplication is a transcription of "×" to "*". -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

28.11.17 22:31, Raymond Hettinger пише:
New syntax often look unusual. "lambda" and "yield" also didn't "look like Python". But there are other considerations. 1. Languages that has the ?? and ?. operators usually have a single special (or at least a one obvious) value that is served for signaling "there-is-no-a-value". The None in Python is not so special. It can be used as a common object, and other ways can be used for denoting an "absent" value. The need of None-specific operators in Python is lower. 2. Python already have other ways for handling "absent" values: the short-circuit "or" and "and" operators which return the one of arguments, getattr() with the default value, the hack with default class attributes, exception handling. The need of the proposed operators in Python is lower. 3. These languages usually have borrowed the syntax of the ternary operator from C: "... ? ... : ...". Thus the syntax with "?" looks more natural in them. But in Python it looks less natural. I'm -1 for accepting this syntax in 3.7. In future all can be changed.

On Tue, Nov 28, 2017, at 15:31, Raymond Hettinger wrote:
Since we're looking at different syntax for the ?? operator, I have a suggestion for the ?. operator - and related ?[] and ?() that appeared in some of the proposals. How about this approach? Something like (or None: ...) as a syntax block in which any operation [lexically within the expression, not within e.g. called functions, so it's different from simply catching AttributeError etc, even if that could be limited to only catching when the operand is None] on None that is not valid for None will yield None instead. This isn't *entirely* equivalent, but offers finer control. v = name?.strip()[4:].upper() under the old proposal would be more or less equivalent to: v = name.strip()[4:].upper() if name is not None else None Whereas, you could get the same result with: (or None: name.strip()[4:].upper()) Though that would technically be equivalent to these steps: v = name.strip if name is not None else None v = v() if v """"" v = v[4:] """"""" v = v.upper """"""" v = v() """"""" The compiler could optimize this case since it knows none of the operations are valid on None. This has the advantage of being explicit about what scope the modified rules apply to, rather than simply implicitly being "to the end of the chain of dot/bracket/call operators" It could also be extended to apply, without any additional syntax, to binary operators (result is None if either operand is None) (or None: a + b), for example, could return None if either a or b is none. [I think I proposed this before with the syntax ?(...), the (or None: ...) is just an idea to make it look more like Python.]

I like much of the thinking in Random's approach. But I still think None isn't quite special enough to warrant it's own syntax. However, his '(or None: name.strip()[4:].upper())' makes me realize that what is being asked in all the '?(', '?.', '?[' syntax ideas is a kind of ternary expression. Except the ternary isn't based on whether a predicate holds, but rather on whether an exception occurs (AttributeError, KeyError, TypeError). And the fallback in the ternary is always None rather than being general. I think we could generalize this to get something both more Pythonic and more flexible. E.g.: val = name.strip()[4:].upper() except None This would just be catching all errors, which is perhaps too broad. But it *would* allow a fallback other than None: val = name.strip()[4:].upper() except -1 I think some syntax could be possible to only "catch" some exceptions and let others propagate. Maybe: val = name.strip()[4:].upper() except (AttributeError, KeyError): -1 I don't really like throwing a colon in an expression though. Perhaps some other word or symbol could work instead. How does this read: val = name.strip()[4:].upper() except -1 in (AttributeError, KeyError) Where the 'in' clause at the end would be optional, and default to 'Exception'. I'll note that what this idea DOES NOT get us is: val = timeout ?? local_timeout ?? global_timeout Those values that are "possibly None" don't raise exceptions, so they wouldn't apply to this syntax. Yours, David... On Wed, Nov 29, 2017 at 9:03 AM, Random832 <random832@fastmail.com> wrote:
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

On Nov 29, 2017, at 12:40, David Mertz <mertz@gnosis.cx> wrote:
I don’t know whether I like any of this <wink> but I think a more natural spelling would be: val = name.strip()[4:].upper() except (AttributeError, KeyError) as -1 which could devolve into: val = name.strip()[4:].upper() except KeyError as -1 or: val = name.strip()[4:].upper() except KeyError # Implicit `as None` I would *not* add any spelling for an explicit bare-except equivalent. You would have to write: val = name.strip()[4:].upper() except Exception as -1 Cheers, -Barry

On 11/29/2017 01:02 PM, Barry Warsaw wrote:
Of all the proposed spellings for the idea, this one feels most "normal" to me, too (I'm -0 on the idea as a whole).
Wouldn't that really need to be this instead, for a true 'except:' equivalence: val = name.strip()[4:].upper() except BaseException as -1 Tres. -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@palladion.com Palladion Software "Excellence by Design" http://palladion.com

Le 29/11/2017 à 19:02, Barry Warsaw a écrit :
I really like this one. It's way more general. I can see a use for IndexError as well (lists don't have the dict.get() method). Also I would prefer not to use "as" this way. In the context of an exception, "as" already binds the exception to a variable so it's confusing. What about: val = name.strip()[4:].upper() except Exception: -1

On Tue, Dec 12, 2017 at 7:39 PM, Michel Desmoulin <desmoulinmichel@gmail.com> wrote:
That happens to be the exact syntax recommended by PEP 463 (modulo some distinguishing parentheses). https://www.python.org/dev/peps/pep-0463/ ChrisA

On Wed, Dec 13, 2017 at 6:03 AM, Guido van Rossum <guido@python.org> wrote:
And I'll never approve syntax to make it easier to just ignore all exceptions without looking at them.
Well, I certainly wouldn't advocate "except Exception: -1", but the syntax is the same as "except KeyError: -1" which is less unreasonable. But PEP 463 was rejected, which means that any proposals along these lines need to first deal with the objections to that PEP, else there's not a lot of point discussing them. ChrisA

On Tue, 28 Nov 2017 12:10:54 -0800 Lukasz Langa <lukasz@langa.pl> wrote:
Hi Mark, it looks like the PEP is dormant for over two years now. I had multiple people ask me over the past few days about it though, so I wanted to ask if this is moving forward.
I am -1 on this PEP. I also think we don't need any additional syntax for the feature, regardless of how it's spelt exactly (or whether it's spelled rather than spelt). Regards Antoine.

Please, not for 3.7. I think it will be very difficult to get consensus about this, and I personally feel something like +/- zero about it -- sometimes I think it makes sense, sometimes I think we're jumping the shark here. On Tue, Nov 28, 2017 at 12:10 PM, Lukasz Langa <lukasz@langa.pl> wrote:
-- --Guido van Rossum (python.org/~guido)

On 29 November 2017 at 06:17, Guido van Rossum <guido@python.org> wrote:
I've marked all 3 of the related PEPs as Deferred until 3.8 at the earliest: https://github.com/python/peps/commit/181cc79af925e06a068733a1419b1760ac1a2d... PEP 505: None-aware operators PEP 532: A circuit breaking protocol and binary operators PEP 535: Rich comparison chaining I don't see any urgency to resolve any of them - the None-aware operators do make certain kinds of code (commonly found in JSON processing) easier to read and write, but such code is still fairly readable and writable today (it's just a bit verbose and boilerplate heavy), and the other two PEPs arise specifically from seeking to provide a common conceptual underpinning for the semantics of both the proposed None-aware operations and the existing short-circuiting logical operators. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

I also cc python-dev to see if anybody here is strongly in favor or against this inclusion.
Put me down for a strong -1. The proposal would occasionally save a few keystokes but comes at the expense of giving Python a more Perlish look and a more arcane feel. One of the things I like about Python is that I can walk non-programmers through the code and explain what it does. The examples in PEP 505 look like a step in the wrong direction. They don't "look like Python" and make me feel like I have to decrypt the code to figure-out what it does. timeout ?? local_timeout ?? global_timeout 'foo' in (None ?? ['foo', 'bar']) requested_quantity ?? default_quantity * price name?.strip()[4:].upper() user?.first_name.upper() Raymond

On Nov 28, 2017, at 15:31, Raymond Hettinger <raymond.hettinger@gmail.com> wrote:
Put me down for a strong -1. The proposal would occasionally save a few keystokes but comes at the expense of giving Python a more Perlish look and a more arcane feel.
I am also -1.
One of the things I like about Python is that I can walk non-programmers through the code and explain what it does. The examples in PEP 505 look like a step in the wrong direction. They don't "look like Python" and make me feel like I have to decrypt the code to figure-out what it does.
I had occasional to speak with someone very involved in Rust development. They have a process roughly similar to our PEPs. One of the things he told me, which I found very interesting and have been mulling over for PEPs is, they require a section in their specification discussion how any new feature will be taught, both to new Rust programmers and experienced ones. I love the emphasis on teachability. Sometimes I really miss that when considering some of the PEPs and the features they introduce (look how hard it is to teach asynchronous programming). Cheers, -Barry

On 28 November 2017 at 20:38, Barry Warsaw <barry@python.org> wrote:
-1 from me, too.
One of the things I like about Python is that I can walk non-programmers through the code and explain what it does. The examples in PEP 505 look like a step in the wrong direction. They don't "look like Python" and make me feel like I have to decrypt the code to figure-out what it does.
I had occasional to speak with someone very involved in Rust development. They have a process roughly similar to our PEPs. One of the things he told me, which I found very interesting and have been mulling over for PEPs is, they require a section in their specification discussion how any new feature will be taught, both to new Rust programmers and experienced ones. I love the emphasis on teachability. Sometimes I really miss that when considering some of the PEPs and the features they introduce (look how hard it is to teach asynchronous programming).
That's a really nice idea. I'd like to see Python adopt something similar (even just as a guideline on how to write a PEP). Paul

On Nov 28, 2017, at 15:59, Paul Moore <p.f.moore@gmail.com> wrote:
On 28 November 2017 at 20:38, Barry Warsaw <barry@python.org> wrote:

Not really related but the PEP says that arguments in Python are evaluated before the function (as a reason to reject the idea of None-aware function call) but this is not the case: >>> import dis >>> dis.dis(lambda : f()(g())) 1 0 LOAD_GLOBAL 0 (f) 3 CALL_FUNCTION 0 6 LOAD_GLOBAL 1 (g) 9 CALL_FUNCTION 0 12 CALL_FUNCTION 1 15 RETURN_VALUE Andrea On Wed, Nov 29, 2017 at 7:14 PM, Joao S. O. Bueno <jsbueno@python.org.br> wrote:

On Thu, Nov 30, 2017 at 2:48 AM, Andrea Griffini <agriff@tin.it> wrote:
I think you're missing something here, since it seems clear to me that indeed the arguments are evaluated prior to the function call. Maybe unrolling it would help? This is equivalent to the body of your lambda, and you can see that the argument is evaluated prior to the call which receives it.
>>> import dis
Call 'f()' with all of its arguments evaluated prior to the call (there are none, that's the '0' on the CALL_FUNCTION operator).
6 LOAD_GLOBAL 1 (g) 9 CALL_FUNCTION 0
Next, evaluate the arguments for the next function call. Call 'g()' with all of its arguments evaluated.
12 CALL_FUNCTION 1
Call the function that 'f()' returned with its argument ('g()') evaluated.

Eric Fahlgren wrote:
I think you're missing something here, since it seems clear to me that indeed the arguments are evaluated prior to the function call.
I think the OP may be confusing "evaluating the function" with "calling the function". If the function being called is determined by some computation, that computation may be performed before its arguments are evaluated (and is probably required to be, by the "left to right" rule). But the arguments will always be evaluated before the actual call happens. -- Greg

On Thu, Nov 30, 2017, at 17:26, Greg Ewing wrote:
Right, but if the function is evaluated before either of those things happen, then it can indeed short-circuit the argument evaluation. The OP isn't confusing anything; it's Eric who is confused. The quoted paragraph of the PEP clearly and unambiguously claims that the sequence is "arguments -> function -> call", meaning that something happens after the "function" stage [i.e. a None check] cannot short-circuit the "arguments" stage. But in fact the sequence is "function -> arguments -> call".

On Thu, Nov 30, 2017 at 11:54:39PM -0500, Random832 wrote:
I'm more confused than ever. You seem to be arguing that Python functions CAN short-circuit their arguments and avoid evaluating them. Is that the case? If not, then I fail to see the difference between "arguments -> function -> call" "function -> arguments -> call" In *both cases* the arguments are fully evaluated before the function is called, and so there is nothing the function can do to delay evaluating its arguments. If this is merely about when the name "function" is looked up, then I don't see why that's relevant to the PEP. What am I missing? -- Steve

On Fri, Dec 1, 2017 at 10:31 AM, Steven D'Aprano <steve@pearwood.info> wrote: the expression immediately to the left of the argument list) and/or the argument has side effects then the evaluation order will affect the outcome. Intuitively it seems more straightforward to compute the function first. If this expression were to raise an exception, of course, then the arguments would not then be evaluated. Or vice versa. It would be best of the specification matches current CPython bahviour.

On Fri, Dec 1, 2017, at 05:31, Steven D'Aprano wrote:
You're completely missing the context of the discussion, which was the supposed reason that a *new* function call operator, with the proposed syntax function?(args), that would short-circuit (based on the 'function' being None) could not be implemented. The whole thing doesn't make sense to me anyway, since a new operator could have its own sequence different from the existing one if necessary.

On Fri, Dec 01, 2017 at 08:24:05AM -0500, Random832 wrote:
Yes I am. That's why I asked.
Given that neither your post (which I replied to) nor the post you were replying to mentioned anything about function?() syntax, perhaps I might be forgiven for having no idea what you were talking about? The PEP only mentions function?() as a rejected idea, do I don't know why we're even talking about it. The PEP is deferred, with considerable opposition and luke-warm support, even the PEP author has said he's not going to push for it, and we're arguing about a pedantic point related to a part of the PEP which is rejected... :-) -- Steve

On 2 December 2017 at 12:01, Steven D'Aprano <steve@pearwood.info> wrote:
Nevertheless, I've fixed the rationale for that decision so folks don't get hung up on the mistake in the previously noted rationale: https://github.com/python/peps/commit/966dd426787e6de8ec6218955cec57f65086c5... Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

The PEP says that a None-aware function call operator (e.g. "f?(x, y)") would break the rule of python that arguments are evaluated before the function but this is not correct. In Python the function is evaluated before the arguments (but of course the CALL is made after the evaluation of the arguments). A None-aware function call operator ?(...) wouldn't break this order of evaluation rule: 1) evaluate the function, 2) only if it's not None evaluate arguments and make the call. In bytecode the None-aware function call would simply require a extra "JNONE" to the end... ... evaluate the function ... JNONE skip ... evaluate arguments ... CALL n skip: Note that I'm not saying this would be a good thing, just that the reason the PEP uses to dismiss this option is actually wrong because Python doesn't work the way the PEP says it does. Andrea On Fri, Dec 1, 2017 at 11:31 AM, Steven D'Aprano <steve@pearwood.info> wrote:

On 29 November 2017 at 07:15, Mark Haase <mehaase@gmail.com> wrote:
We should probably set the state of both this and the related circuit breaking protocol PEPs to Deferred so folks know neither of us is actually working on them. While I still think there's merit to the idea of making it easier to write concise data cleanup pipelines in Python, I find the argument "The currently proposed spelling doesn't even come close to reading like executable pseudo code" to be a compelling one. I think a big part of the problem is that these kinds of data cleanup operations don't even have a good *vocabulary* around them yet, so nobody actually knows how to write them as pseudo code in the first place - we only know how to express them in particular programming languages. Trying to come up with pseudo code for the example cases Raymond mentioned: timeout if defined, else local_timeout if defined, else global_timeout price * (requested_quantity if defined, else default_quantity) name if not defined, else name.strip()[4:].upper() user if not defined, else name.first_name.upper() And that's not actually that different to their current spellings in Python: timeout if timeout is not None else local_timeout if local_timeout is not None, else global_timeout price * (requested_quantity if requested_quantity is not None else default_quantity) name if name is None else name.strip()[4:].upper() user if user is None else name.first_name.upper() One key aspect that Python does miss relative to the pseudocode versions is that we don't actually have a term for "expr is not None". "def" is used specifically for functions, so "defined" isn't reference right. References to "None" are bound like anything else, so "bound" isn't right. "exists" probably comes closest (hence the title of the withdrawn PEP 531). That said, if we did decide to allow "def" in a conditional expression to mean "defined" in the "lhs is not None" sense, it would look like: timeout if def else local_timeout if def else global_timeout price * (requested_quantity if def else default_quantity) name if not def else name.strip()[4:].upper() user if not def else user.first_name.upper() Cheers, Nick. P.S. Compared to this, our last symbolic feature addition (matrix multiplication), was a relatively straightforward transcription of "⋅" to "@", just as regular multiplication is a transcription of "×" to "*". -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

28.11.17 22:31, Raymond Hettinger пише:
New syntax often look unusual. "lambda" and "yield" also didn't "look like Python". But there are other considerations. 1. Languages that has the ?? and ?. operators usually have a single special (or at least a one obvious) value that is served for signaling "there-is-no-a-value". The None in Python is not so special. It can be used as a common object, and other ways can be used for denoting an "absent" value. The need of None-specific operators in Python is lower. 2. Python already have other ways for handling "absent" values: the short-circuit "or" and "and" operators which return the one of arguments, getattr() with the default value, the hack with default class attributes, exception handling. The need of the proposed operators in Python is lower. 3. These languages usually have borrowed the syntax of the ternary operator from C: "... ? ... : ...". Thus the syntax with "?" looks more natural in them. But in Python it looks less natural. I'm -1 for accepting this syntax in 3.7. In future all can be changed.

On Tue, Nov 28, 2017, at 15:31, Raymond Hettinger wrote:
Since we're looking at different syntax for the ?? operator, I have a suggestion for the ?. operator - and related ?[] and ?() that appeared in some of the proposals. How about this approach? Something like (or None: ...) as a syntax block in which any operation [lexically within the expression, not within e.g. called functions, so it's different from simply catching AttributeError etc, even if that could be limited to only catching when the operand is None] on None that is not valid for None will yield None instead. This isn't *entirely* equivalent, but offers finer control. v = name?.strip()[4:].upper() under the old proposal would be more or less equivalent to: v = name.strip()[4:].upper() if name is not None else None Whereas, you could get the same result with: (or None: name.strip()[4:].upper()) Though that would technically be equivalent to these steps: v = name.strip if name is not None else None v = v() if v """"" v = v[4:] """"""" v = v.upper """"""" v = v() """"""" The compiler could optimize this case since it knows none of the operations are valid on None. This has the advantage of being explicit about what scope the modified rules apply to, rather than simply implicitly being "to the end of the chain of dot/bracket/call operators" It could also be extended to apply, without any additional syntax, to binary operators (result is None if either operand is None) (or None: a + b), for example, could return None if either a or b is none. [I think I proposed this before with the syntax ?(...), the (or None: ...) is just an idea to make it look more like Python.]

I like much of the thinking in Random's approach. But I still think None isn't quite special enough to warrant it's own syntax. However, his '(or None: name.strip()[4:].upper())' makes me realize that what is being asked in all the '?(', '?.', '?[' syntax ideas is a kind of ternary expression. Except the ternary isn't based on whether a predicate holds, but rather on whether an exception occurs (AttributeError, KeyError, TypeError). And the fallback in the ternary is always None rather than being general. I think we could generalize this to get something both more Pythonic and more flexible. E.g.: val = name.strip()[4:].upper() except None This would just be catching all errors, which is perhaps too broad. But it *would* allow a fallback other than None: val = name.strip()[4:].upper() except -1 I think some syntax could be possible to only "catch" some exceptions and let others propagate. Maybe: val = name.strip()[4:].upper() except (AttributeError, KeyError): -1 I don't really like throwing a colon in an expression though. Perhaps some other word or symbol could work instead. How does this read: val = name.strip()[4:].upper() except -1 in (AttributeError, KeyError) Where the 'in' clause at the end would be optional, and default to 'Exception'. I'll note that what this idea DOES NOT get us is: val = timeout ?? local_timeout ?? global_timeout Those values that are "possibly None" don't raise exceptions, so they wouldn't apply to this syntax. Yours, David... On Wed, Nov 29, 2017 at 9:03 AM, Random832 <random832@fastmail.com> wrote:
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

On Nov 29, 2017, at 12:40, David Mertz <mertz@gnosis.cx> wrote:
I don’t know whether I like any of this <wink> but I think a more natural spelling would be: val = name.strip()[4:].upper() except (AttributeError, KeyError) as -1 which could devolve into: val = name.strip()[4:].upper() except KeyError as -1 or: val = name.strip()[4:].upper() except KeyError # Implicit `as None` I would *not* add any spelling for an explicit bare-except equivalent. You would have to write: val = name.strip()[4:].upper() except Exception as -1 Cheers, -Barry

On 11/29/2017 01:02 PM, Barry Warsaw wrote:
Of all the proposed spellings for the idea, this one feels most "normal" to me, too (I'm -0 on the idea as a whole).
Wouldn't that really need to be this instead, for a true 'except:' equivalence: val = name.strip()[4:].upper() except BaseException as -1 Tres. -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@palladion.com Palladion Software "Excellence by Design" http://palladion.com

Le 29/11/2017 à 19:02, Barry Warsaw a écrit :
I really like this one. It's way more general. I can see a use for IndexError as well (lists don't have the dict.get() method). Also I would prefer not to use "as" this way. In the context of an exception, "as" already binds the exception to a variable so it's confusing. What about: val = name.strip()[4:].upper() except Exception: -1

On Tue, Dec 12, 2017 at 7:39 PM, Michel Desmoulin <desmoulinmichel@gmail.com> wrote:
That happens to be the exact syntax recommended by PEP 463 (modulo some distinguishing parentheses). https://www.python.org/dev/peps/pep-0463/ ChrisA

On Wed, Dec 13, 2017 at 6:03 AM, Guido van Rossum <guido@python.org> wrote:
And I'll never approve syntax to make it easier to just ignore all exceptions without looking at them.
Well, I certainly wouldn't advocate "except Exception: -1", but the syntax is the same as "except KeyError: -1" which is less unreasonable. But PEP 463 was rejected, which means that any proposals along these lines need to first deal with the objections to that PEP, else there's not a lot of point discussing them. ChrisA

On Tue, 28 Nov 2017 12:10:54 -0800 Lukasz Langa <lukasz@langa.pl> wrote:
Hi Mark, it looks like the PEP is dormant for over two years now. I had multiple people ask me over the past few days about it though, so I wanted to ask if this is moving forward.
I am -1 on this PEP. I also think we don't need any additional syntax for the feature, regardless of how it's spelt exactly (or whether it's spelled rather than spelt). Regards Antoine.
participants (25)
-
Andrea Griffini
-
Antoine Pitrou
-
Barry Warsaw
-
Chris Angelico
-
Christian Heimes
-
David Mertz
-
Eric Fahlgren
-
Eric V. Smith
-
Ethan Furman
-
Greg Ewing
-
Guido van Rossum
-
Joao S. O. Bueno
-
Lukasz Langa
-
Mariatta Wijaya
-
Mark Haase
-
Michel Desmoulin
-
MRAB
-
Nick Coghlan
-
Paul Moore
-
Random832
-
Raymond Hettinger
-
Serhiy Storchaka
-
Steve Holden
-
Steven D'Aprano
-
Tres Seaver