Re: [Python-ideas] PEP 505: None-aware operators: operators ?= and ?? and OR

2018-08-03 Thread Eric Fahlgren
On Fri, Aug 3, 2018 at 6:19 PM Steven D'Aprano  wrote:

> It needs some work. Something like "Here's an example in the standard
> library. On converting it to none-aware version, we realised the std lib
> version is buggy, because ...". A couple of sentences.
>

Yup, that's what I was getting at...
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators: operators ?= and ?? and OR

2018-08-03 Thread Steven D'Aprano
On Fri, Aug 03, 2018 at 06:30:25AM -0700, Eric Fahlgren wrote:

> After looking at the code a bit more, I agree, we've uncovered a bug in the
> stdlib and the null coalescing version actually fixes it.
[...]
> But!  We are not here to talk about bugs in the email package, this
> discussion is about PEP 505, which means to me that the example is a bug in
> the PEP.

On the contrary! It strongly suggests to me that None-aware operators, 
or at least this one, makes it *easier* to write correct code than 
incorrect code.

If your analysis that the email package is buggy is correct, this is a 
strong example in favour of the none-aware operator.


> In my view, the before and after examples should have identical
> results, unless there is some very clear and thorough discussion
> accompanying the example as to why they are different and more importantly,
> why the "after" version is better or worse.  In this light, the example
> certainly needs a lot of work.

It needs some work. Something like "Here's an example in the standard 
library. On converting it to none-aware version, we realised the std lib 
version is buggy, because ...". A couple of sentences.


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


Re: [Python-ideas] PEP 505: None-aware operators: operators ?= and ?? and OR

2018-08-03 Thread Eric Fahlgren
On Thu, Aug 2, 2018 at 10:06 PM Alexandre Brault 
wrote:

> I would make the opposite argument and claim that since when policy is
> None mangle_from_ is initialised to True and not None, None is likely not a
> potential value for policy.mangle_from_. Looking at
> Lib/email/_policybase.py where the abstract policy class in question is
> defined, policies default their mangle_from_ to False, which gives
> additional credence to the notion that policy.mangle_from_ is not meant to
> be None.
>

After looking at the code a bit more, I agree, we've uncovered a bug in the
stdlib and the null coalescing version actually fixes it.

So yes, *strictly speaking* the two chunks of code are not exactly the
> same. In practice, they'll act the same way given sensible inputs.
>

But!  We are not here to talk about bugs in the email package, this
discussion is about PEP 505, which means to me that the example is a bug in
the PEP.  In my view, the before and after examples should have identical
results, unless there is some very clear and thorough discussion
accompanying the example as to why they are different and more importantly,
why the "after" version is better or worse.  In this light, the example
certainly needs a lot of work.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators: operators ?= and ?? and OR

2018-08-03 Thread Jonathan Fine
Hi Alexandre

Thank you for your post.

In PEP 505 the context for the example being discussed is:

> Some of these are shown below as examples before and after converting to use 
> the new operators.

You wrote:
> So yes, *strictly speaking* the two chunks of code are not exactly the same.

I see nothing in the context that indicates that given suitable
(Python) context, the before and after expressions give different
values. I assumed the before and after values were intended to be the
same.

By the way, I think that even without your *strictly speaking*, the
two chunks of code are not exactly the same (in that they can give
different values from identical inputs).

> In practice, they'll act the same way given sensible inputs.

For me, the truth or falsity of this statement requires more than the
peep-hole view of the code supplied by the PEP. Your argument for its
truth certainly looked beyond the PEP.

I think lack of clarity can mislead, and prevents the PEP performing
properly one of its key functions
===
https://www.python.org/dev/peps/pep-0001/#what-is-a-pep
The PEP should provide a concise technical specification of the
feature and a rationale for the feature [being proposed].
===
and so is a bug in the PEP. Fixing it will help the progress of the PEP.

Where to report the bug? Either to Steve Dower, or raise an issue on github.
https://www.python.org/dev/peps/pep-0001/#reporting-pep-bugs-or-submitting-pep-updates

Steve's already been emailed on this. We're waiting to hear back from him.

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


Re: [Python-ideas] PEP 505: None-aware operators: operators ?= and ?? and OR

2018-08-02 Thread Alexandre Brault

On 2018-08-02 7:01 PM, Eric Fahlgren wrote:
On Thu, Aug 2, 2018 at 3:39 PM MRAB > wrote:


In the relevant code, is policy.mangle_from_ ever None?


That's impossible to know, since the initializer where this code 
originally appears puts no constraints on the value of 'policy', it's 
just assumed to have a 'mangle_from_' member...  I would be paranoid 
and assume, yes, it can take on a value of None as there's nothing to 
indicate that it can't.


I would make the opposite argument and claim that since when policy is 
None mangle_from_ is initialised to True and not None, None is likely 
not a potential value for policy.mangle_from_. Looking at 
Lib/email/_policybase.py where the abstract policy class in question is 
defined, policies default their mangle_from_ to False, which gives 
additional credence to the notion that policy.mangle_from_ is not meant 
to be None.


So yes, *strictly speaking* the two chunks of code are not exactly the 
same. In practice, they'll act the same way given sensible inputs.


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


Re: [Python-ideas] PEP 505: None-aware operators: operators ?= and ?? and OR

2018-08-02 Thread Steven D'Aprano
On Thu, Aug 02, 2018 at 06:50:47PM +0200, Pål Grønås Drange wrote:
> > Reads the same out loud despite being a different operator.
> 
> How are `??`, `.?`, and the others pronounced?

Did you read the PEP? It answers that question.

https://www.python.org/dev/peps/pep-0505/#reading-expressions

I'm happy to read them as:

spam ?? eggs
spam maybe eggs
spam or eggs if None

spam?.eggs
spam maybe-dot eggs
spam dot eggs if not None


etc depending on context. But I expect that some clever person will 
think up a nickname for it, like the Elvis operator:

https://en.wikipedia.org/wiki/Elvis_operator


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


Re: [Python-ideas] PEP 505: None-aware operators: operators ?= and ?? and OR

2018-08-02 Thread Eric Fahlgren
On Thu, Aug 2, 2018 at 3:39 PM MRAB  wrote:

> In the relevant code, is policy.mangle_from_ ever None?
>

That's impossible to know, since the initializer where this code originally
appears puts no constraints on the value of 'policy', it's just assumed to
have a 'mangle_from_' member...  I would be paranoid and assume, yes, it
can take on a value of None as there's nothing to indicate that it can't.

class Generator:
...
def __init__(self, outfp, mangle_from_=None, maxheaderlen=None, *,
 policy=None):
...
if mangle_from_ is None:
mangle_from_ = True if policy is None else policy.mangle_from_
self._fp = outfp
self._mangle_from_ = mangle_from_
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators: operators ?= and ?? and OR

2018-08-02 Thread MRAB

On 2018-08-02 22:49, Eric Fahlgren wrote:


On Thu, Aug 2, 2018 at 1:22 PM MRAB > wrote:


> policy?.mangle_from_ ?? True
> True (??? since lhs is None?)
>
No, it's not 'policy.mangle_from_' that could be None, it's 'policy'
that could be None (i.e. there's no policy).


In my example, there is a policy, and the value of policy.mangle_from_ 
is set to None.  Thus the above should be equivalent to this


>>> None ?? True
True

Unless, of course, I completely misunderstand the way the ?? operator 
works.  This is not the same as the original code, they are not 
equivalent.

In the relevant code, is policy.mangle_from_ ever None?

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


Re: [Python-ideas] PEP 505: None-aware operators: operators ?= and ?? and OR

2018-08-02 Thread Eric Fahlgren
On Thu, Aug 2, 2018 at 1:22 PM MRAB  wrote:

> > policy?.mangle_from_ ?? True
> > True (??? since lhs is None?)
> >
> No, it's not 'policy.mangle_from_' that could be None, it's 'policy'
> that could be None (i.e. there's no policy).
>

In my example, there is a policy, and the value of policy.mangle_from_ is
set to None.  Thus the above should be equivalent to this

>>> None ?? True
True

Unless, of course, I completely misunderstand the way the ?? operator
works.  This is not the same as the original code, they are not equivalent.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators: operators ?= and ?? and OR

2018-08-02 Thread MRAB

On 2018-08-02 20:03, Eric Fahlgren wrote:

 From the PEP:
 >
 From email/generator.py (and importantly note that there is no way to 
substitute or for ?? in this situation):

 >
mangle_from_ = True if policy is None else policy.mangle_from_
 > After updating:
 >
mangle_from_ =
policy?.mangle_from_ ?? True

I cannot see how these are equivalent, and cannot understand what the 
cryptic comment means.



If there's a policy, use policy.mangle_from_.

If there's no policy, default to True.

The comment is a reminder that you can't use 'or' instead of '??' 
because 'policy.mangle_from_' could be False and you don't want it to 
default to True in that case.



 >>> policy.mangle_from_ = None
 >>>
True if policy is None else policy.mangle_from_
None

 >>>
policy?.mangle_from_ ?? True
True (??? since lhs is None?)

No, it's not 'policy.mangle_from_' that could be None, it's 'policy' 
that could be None (i.e. there's no policy).

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


Re: [Python-ideas] PEP 505: None-aware operators: operators ?= and ?? and OR

2018-08-02 Thread Jonathan Fine
Hi Eric

[Steve Dower: Eric seems to have found a bug in the PEP. Where to report?]

You quoted, from PEP 505,

Before
> mangle_from_ = True if policy is None else policy.mangle_from_

After
> mangle_from_ = policy?.mangle_from_ ?? True

You then remarked
> I cannot see how these are equivalent

I don't see the equivalence either. If `policy.mangle_from_ is None`
then surely Before gives None, while After gives True.

Here's the process for filing bugs in a PEP
https://www.python.org/dev/peps/pep-0001/#reporting-pep-bugs-or-submitting-pep-updates

As we seem to be in early draft stage, perhaps communicate first with
PEP author (Steve Dower, copied).

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


Re: [Python-ideas] PEP 505: None-aware operators: operators ?= and ?? and OR

2018-08-02 Thread Eric Fahlgren
>From the PEP:
>
>From email/generator.py (and importantly note that there is no way to
substitute or for ?? in this situation):
>
mangle_from_ = True if policy is None else policy.mangle_from_
> After updating:
>
mangle_from_ =
policy?.mangle_from_ ?? True

I cannot see how these are equivalent, and cannot understand what the
cryptic comment means.

>>> policy.mangle_from_ = None
>>>
True if policy is None else policy.mangle_from_
None

>>>
policy?.mangle_from_ ?? True
True (??? since lhs is None?)
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators: operators ?= and ?? and OR

2018-08-02 Thread David Foster

RE none-aware operators in general:
+1 overall for the latest version of PEP 505 and the utility of ?? in 
particular. There are several places in my code that could be simplified 
with ??.


find-pep505.py on my current Django-oriented codebase gives:
Total None-coalescing `if` blocks: 43
Total [possible] None-coalescing `or`: 4
Total None-coalescing ternaries: 8
Total Safe navigation `and`: 0
Total Safe navigation `if` blocks: 6
Total Safe navigation ternaries: 17

RE OR and ||:
* -1 for "OR" as an operator. Insufficiently distinct from "or". Reads 
the same out loud despite being a different operator.
* -1 for "||" with none-aware semantics. This differs from the semantics 
in every C-derived language I can think of, which will be confusing to 
several other developers.


David Foster | Seattle, WA, USA

On 7/19/18 5:30 AM, Jonathan Fine wrote:

Hi


There is a formatted version of this PEP at
https://www.python.org/dev/peps/pep-0505/


I've taken a look at this, and have some comments on the first two
examples drawn from standard library code. (And a very grateful +10
for writing a script to find such examples.)

I've started a subthread, just to discuss the ?= and ?? operators. And
something newish, that I call OR.

FIRST EXAMPLE
The first example is
---
 From bisect.py:
def insort_right(a, x, lo=0, hi=None):
 # ...
 if hi is None:
 hi = len(a)
---

Here, None is a sentinel value. The simpler code
---
   hi = hi or len(a)
---
fails when hi is zero (or any other value that is False in the boolean context).

This can be fixed by introducing a new operator OR which is similar to
'or' but has the semantics this example requires. Thus, given OR we
can write
---
   hi = hi OR len(a)
---
where (A OR B) returns A if A is not None, otherwise it returns B.

(Recall that (A or B) returns A if bool(A), otherwise it returns B.)

SECOND EXAMPLE
The second example is
---
 From calendar.py:
encoding = options.encoding
if encoding is None:
 encoding = sys.getdefaultencoding()
optdict = dict(encoding=encoding, css=options.css)
---

Once we have OR we would write this as
---
encoding = encoding OR sys.getdefaultencoding()
optdict = dict(encoding=encoding, css=options.css)
---

And from here we can condense into a single (longish) line:
---
optdict = dict(encoding=encoding OR sys.getdefaultencoding(), css=options.css)
--

SUMMARY
Here, for reference, are the suggestions using ?= and ?? in PEP 505.
---
hi ??= len(a)
---
optdict = dict(encoding=encoding ?? sys.getdefaultencoding(), css=options.css)
---

Comments ?? suggestions. For example, would a None-aware AND operator be useful?


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Chris Angelico
On Thu, Aug 2, 2018 at 12:04 AM, Jonathan Fine  wrote:
> Hi Steve
>
> Thank you for your reply.
>
> We're discussing the abstract to PEP 505, which writes
>  ===
> The "None-aware attribute access" operator ?. ("maybe dot") evaluates
> the complete expression if the left hand side evaluates to a value
> that is not None
> ===
>
> I gave (42).str as an example. I wrote
>
>> I don't see how to apply the prose in the abstract to this last
>> example. The left hand side is not None, so we "evaluate the complete
>> expression". On one reading, this is a recursion.
>
> You wrote
>> The phrasing could be clearer.
>
> I think the phrasing could be considerably improved (see below).
>
>> Since 42 is not None, it evaluates (42).str
>> [...]
>
> Based on this hint, here's what I think is a better statement.
> ===
> Let `lhs` be the value of the left hand side, and RHS the code
> fragment on the right hand side. If `lhs` is None, then the whole
> expression is `None`. Otherwise, `lhs . RHS` gives the value of the
> whole expression.
> ===
>
> Please would the experts tell me: Is it true? And if true, is it
> better? And can it be improved?

It may be true, but it isn't better IMO - especially not for the
abstract. It's unnecessarily pedantic. The current wording isn't
ambiguous, because infinite recursion makes no sense.

MAYBE change it to "evaluate the rest of the expression", but I don't
see a problem with the current wording.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Jonathan Fine
Hi Steve

Thank you for your reply.

We're discussing the abstract to PEP 505, which writes
 ===
The "None-aware attribute access" operator ?. ("maybe dot") evaluates
the complete expression if the left hand side evaluates to a value
that is not None
===

I gave (42).str as an example. I wrote

> I don't see how to apply the prose in the abstract to this last
> example. The left hand side is not None, so we "evaluate the complete
> expression". On one reading, this is a recursion.

You wrote
> The phrasing could be clearer.

I think the phrasing could be considerably improved (see below).

> Since 42 is not None, it evaluates (42).str
> [...]

Based on this hint, here's what I think is a better statement.
===
Let `lhs` be the value of the left hand side, and RHS the code
fragment on the right hand side. If `lhs` is None, then the whole
expression is `None`. Otherwise, `lhs . RHS` gives the value of the
whole expression.
===

Please would the experts tell me: Is it true? And if true, is it
better? And can it be improved?

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Steven D'Aprano
On Wed, Aug 01, 2018 at 11:03:05AM +0100, Jonathan Fine wrote:

[...]
> After my last post, you wrote
> > None.?__str__
> > produces None, even though None has a __str__ attribute.
> 
> This surprises me. But I think it follows from the rules in
> https://www.python.org/dev/peps/pep-0505/#the-maybe-dot-and-maybe-subscript-operators

Correct. None?.__str__ is equivalent to:

_v = None
if _v is not None:
_v = _v.__str__
return _v

(except no actual _v variable is created, and it is not literally a 
return statement).


> My initial reading of
> >>> a ?. b
> was that if 'a' didn't have a 'b' attribute, then the result was None,
> whatever the string 'b'.
> 
> In other words, the same as
> >> getattr(a, name, None)

No. PEP 505 is for None-aware operators. It spends considerable time 
explaining that it treats None as special. It does not catch 
AttributeError from missing attributes.

(45)?.upper()

will fail with AttributeError, same as (45).upper() does.



> The abstract to PEP 505 writes
> ===
> The "None-aware attribute access" operator ?. ("maybe dot") evaluates
> the complete expression if the left hand side evaluates to a value
> that is not None
> ===
> 
> This is, of course, informal prose. I'm now reading it carefully.
> Here's a specific example.
> 
> >>> (42).__str__
> 
> >>> (42).str
> Traceback (most recent call last):
> AttributeError: 'int' object has no attribute 'str'
> >>> (42) ?. str
> 
> I don't see how to apply the prose in the abstract to this last
> example. The left hand side is not None, so we "evaluate the complete
> expression". On one reading, this is a recursion.

The phrasing could be clearer.

Since 42 is not None, it evaluates (42).str which of course will 
fail with AttributeError. To be specific, it is equivalent to something 
like this pseudo-code:

_v = 42
if _v is not None:
_v = _v.str
return _v

(The same disclaimer about _v and return apply as earlier.)




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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Jonathan Fine
Hi Stephan

You wrote

> Let me stand up and claim that if a chain consists *only* of None-coalescing
> operations, then breaking up the chain by adding parentheses does not
> matter, ever.

You missed a post I made, 17 minutes before yours. I then believed
that PEP 505 specified.

#1. (None ?. dne) is None
#2. (None ?. dne ?. __str__) is None
#3. (None.__str__) is not None
#4. ((None ?. dne) ?. __str__) is (None.__str__)

After my last post, you wrote
> None.?__str__
> produces None, even though None has a __str__ attribute.

This surprises me. But I think it follows from the rules in
https://www.python.org/dev/peps/pep-0505/#the-maybe-dot-and-maybe-subscript-operators

My initial reading of
>>> a ?. b
was that if 'a' didn't have a 'b' attribute, then the result was None,
whatever the string 'b'.

In other words, the same as
>> getattr(a, name, None)

But you and I agree, I think, that PEP 505 specifies (in the cited
page fragment)
>>> a ?. anything
is always None, whenever 'a' is None, and for any non-keyword
identifier instead of 'anything'. Thank you for contributing this
clarification.

The abstract to PEP 505 writes
===
The "None-aware attribute access" operator ?. ("maybe dot") evaluates
the complete expression if the left hand side evaluates to a value
that is not None
===

This is, of course, informal prose. I'm now reading it carefully.
Here's a specific example.

>>> (42).__str__

>>> (42).str
Traceback (most recent call last):
AttributeError: 'int' object has no attribute 'str'
>>> (42) ?. str

I don't see how to apply the prose in the abstract to this last
example. The left hand side is not None, so we "evaluate the complete
expression". On one reading, this is a recursion.

I'd very much appreciate some help here.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Chris Angelico
On Wed, Aug 1, 2018 at 7:09 PM, Jonathan Fine  wrote:
> Hi Chris
>
> We're discussing.
>> 10) a ?. b ?. c
>> 11) (a ?. b) ?. c
>
> I asked
>> So, are there any values of 'a' for which #10 and #11 don't give the
>> same result?
>
> You replied
>> I'm not prepared to put my neck out and say "They are absolutely
>> identical" and have people jump on me with some technicality. What is
>> your point here?
>
> I am willing to put my neck out and say a.b.c and (a.b).c are
> equivalent. And my understanding for PEP 505 is that #10 and #11 is
> that they are equivalent.

The first pair are easily proven, since we can just probe existing code.

>>> import dis
>>> dis.dis(lambda a: a.b.c)
  1   0 LOAD_FAST0 (a)
  2 LOAD_ATTR0 (b)
  4 LOAD_ATTR1 (c)
  6 RETURN_VALUE
>>> dis.dis(lambda a: (a.b).c)
  1   0 LOAD_FAST0 (a)
  2 LOAD_ATTR0 (b)
  4 LOAD_ATTR1 (c)
  6 RETURN_VALUE
>>>

Same byte code? Same result. Unless there's a bug in the peephole
optimizer or something, which I doubt.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Stephan Houben
Op wo 1 aug. 2018 11:10 schreef Jonathan Fine :

>
>
> You're right to be cautious. My understanding of PEP 505 is that
> #13.  a ?. b ?. __str__
> #14. (a ?. b) ?. __str__
> are not equivalent. The first is None, and the other is None.__str__.
> That looks like a gotcha.
>


No.
None.?__str__
produces None, even though None has a __str__ attribute.

I am pretty sure
a?.b?.c == (a?.b)?.c

and more generically

chain_A ?. chain_B == (chain_A) ?. chain_B

Stephan


> (By the way, it was not my intention to catch you out. I'm simply
> looking for clarity. I wasn't aware of the gotcha until I started
> answering myself the question I had asked you.)
>
> However, the None object is somewhat special, in that all it's methods
> and double-under (dunder) methods. And one of them is __bool__.  And
> we can't add or change the attributes of None.
>
> Chris, you don't have to reply to this. But I would be pleased if an
> expert could either tell me that my neck is safe, or produce a value
> of 'a' that cuts it off (so to speak).
>
> --
> Jonathan
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Stephan Houben
Op wo 1 aug. 2018 10:50 schreef Chris Angelico :

> On Wed, Aug 1, 2018 at 6:45 PM, Jonathan Fine  wrote:
> > Hi Chris
> >
> > Thank you for your reply. I think we're making good progress.
> >
> > You wrote
> >
> >>> 10) a ?. b ?. c
> >>> 11) (a ?. b) ?. c
> >>
> >> I would parse those differently, but you may be right that they'll
> >> always have the same final result.
> >
> > I'd like to get some certainty on this. I'm not aware of any value of
> > 'a' for which #10 and #11 give different values. Can you (or anyone
> > else) think of any such value?
> >
> >> Technically they should result in different code, though.
> >
> > Maybe. We need to think. Should can be a difficult word. Elsewhere you
> > have, as I recall, pointed out that
> > if None:
> > do_something()
> > generates no code.
> >
> > Perhaps the compiler should collapse #11 to #10, if they are
> > equivalent. But this is a side issue.
> >
> > So, are there any values of 'a' for which #10 and #11 don't give the
> > same result?
>
> I'm not prepared to put my neck out and say "They are absolutely
> identical" and have people jump on me with some technicality.


Let me stand up and claim that if a chain consists *only* of
None-coalescing operations, then breaking up the chain by adding
parentheses does not matter, ever.

 So a?.b?.c is equivalent to (a?.b)?.c


What is
> your point here?
>

It is useful to establish rules under which a chain can be factored.

Stephan




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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Jonathan Fine
Hi Chris

We're discussing.
> 10) a ?. b ?. c
> 11) (a ?. b) ?. c

I asked
> So, are there any values of 'a' for which #10 and #11 don't give the
> same result?

You replied
> I'm not prepared to put my neck out and say "They are absolutely
> identical" and have people jump on me with some technicality. What is
> your point here?

I am willing to put my neck out and say a.b.c and (a.b).c are
equivalent. And my understanding for PEP 505 is that #10 and #11 is
that they are equivalent.

You're right to be cautious. My understanding of PEP 505 is that
#13.  a ?. b ?. __str__
#14. (a ?. b) ?. __str__
are not equivalent. The first is None, and the other is None.__str__.
That looks like a gotcha.

(By the way, it was not my intention to catch you out. I'm simply
looking for clarity. I wasn't aware of the gotcha until I started
answering myself the question I had asked you.)

However, the None object is somewhat special, in that all it's methods
and double-under (dunder) methods. And one of them is __bool__.  And
we can't add or change the attributes of None.

Chris, you don't have to reply to this. But I would be pleased if an
expert could either tell me that my neck is safe, or produce a value
of 'a' that cuts it off (so to speak).

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Chris Angelico
On Wed, Aug 1, 2018 at 6:45 PM, Jonathan Fine  wrote:
> Hi Chris
>
> Thank you for your reply. I think we're making good progress.
>
> You wrote
>
>>> 10) a ?. b ?. c
>>> 11) (a ?. b) ?. c
>>
>> I would parse those differently, but you may be right that they'll
>> always have the same final result.
>
> I'd like to get some certainty on this. I'm not aware of any value of
> 'a' for which #10 and #11 give different values. Can you (or anyone
> else) think of any such value?
>
>> Technically they should result in different code, though.
>
> Maybe. We need to think. Should can be a difficult word. Elsewhere you
> have, as I recall, pointed out that
> if None:
> do_something()
> generates no code.
>
> Perhaps the compiler should collapse #11 to #10, if they are
> equivalent. But this is a side issue.
>
> So, are there any values of 'a' for which #10 and #11 don't give the
> same result?

I'm not prepared to put my neck out and say "They are absolutely
identical" and have people jump on me with some technicality. What is
your point here?

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Jonathan Fine
Hi Chris

Thank you for your reply. I think we're making good progress.

You wrote

>> 10) a ?. b ?. c
>> 11) (a ?. b) ?. c
>
> I would parse those differently, but you may be right that they'll
> always have the same final result.

I'd like to get some certainty on this. I'm not aware of any value of
'a' for which #10 and #11 give different values. Can you (or anyone
else) think of any such value?

> Technically they should result in different code, though.

Maybe. We need to think. Should can be a difficult word. Elsewhere you
have, as I recall, pointed out that
if None:
do_something()
generates no code.

Perhaps the compiler should collapse #11 to #10, if they are
equivalent. But this is a side issue.

So, are there any values of 'a' for which #10 and #11 don't give the
same result?

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Chris Angelico
On Wed, Aug 1, 2018 at 6:00 PM, Jonathan Fine  wrote:
> Hi Chris
>
> You wrote:
>
>> Oh. The equivalent ones are #1 and #2, and #7 and #8, where this
>> proposal doesn't change anything. Otherwise, they're not equivalent.
>
> Are you sure. I'd also expect #10 and #11 to be equivalent.
>
> By the way, there's a typo in my examples: 11) (a .? b) ?. c

Hmm.

> 10) a ?. b ?. c
> 11) (a ?. b) ?. c

I would parse those differently, but you may be right that they'll
always have the same final result. Technically they should result in
different code, though.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Jonathan Fine
Hi Chris

You wrote:

> Oh. The equivalent ones are #1 and #2, and #7 and #8, where this
> proposal doesn't change anything. Otherwise, they're not equivalent.

Are you sure. I'd also expect #10 and #11 to be equivalent.

By the way, there's a typo in my examples: 11) (a .? b) ?. c

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Jonathan Fine
Hi Chris

Thank you for your prompt reply. You wrote

> Incorrect. The short-circuiting behaviour ends at any sort of
> grouping. It's like how "a < b < c" is not equivalent to "(a < b) <
> c", nor to "a < (b < c)".

You've told me that my answer B is wrong. But you've not provided your
correct answer. I'd be most grateful if you could tell me what are the
equivalences between the 12 expressions I provided.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Chris Angelico
On Wed, Aug 1, 2018 at 5:29 PM, Jonathan Fine  wrote:
> Hi All
>
> I have two further questions. I'm keen to clarify what is the
> behaviour specified by PEP 505. I'm not, at this time, interested in
> why and how PEP 505 specifies behaviour. I just wish, through explicit
> examples, to clarify the behaviour that is specified.
>
> Here 'a' is an identifier. Consider the following 12 expressions (I
> use the word loosely).
>
> 1) a . b . c
> 2) (a . b) . c
> 3) a . (b . c)
>
> 4) a ?. b . c
> 5) (a ?. b) . c
> 6) a ?. (b . c)
>
> 7) a . b ?. c
> 8) (a . b) ?. c
> 9) a . (b ?. c)
>
> 10) a ?. b ?. c
> 11) (a .? b) ?. c
> 12) a ?. (b ?. c)
>
> Question A: Which of the expressions are NOT valid (Python + PEP 505) syntax?
> Question B: Which of the valid (Python + PEP 505) expressions are
> equivalent, for all possible values of 'a'.
>
> The answer depends, of course, on the exact text of PEP 505. I've not
> read PEP 505 that closely. My expectations, based on my Python
> experience, are that PEP 505 would be written so that:
>
> Answer A: Expressions 3, 6, 9 and 12 are invalid. The others are valid.

Correct. After a dot (whether ?. or plain . ), you need a NAME, not
any form of expression (test, expr, etc).

> Answer B: 1 and 2 are equivalent. Similarly 4 and 5. Similarly 7 and
> 8. Similarly 10 and 11. There are no other equivalences (for all
> values of 'a').

Incorrect. The short-circuiting behaviour ends at any sort of
grouping. It's like how "a < b < c" is not equivalent to "(a < b) <
c", nor to "a < (b < c)".

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-08-01 Thread Jonathan Fine
Hi All

I have two further questions. I'm keen to clarify what is the
behaviour specified by PEP 505. I'm not, at this time, interested in
why and how PEP 505 specifies behaviour. I just wish, through explicit
examples, to clarify the behaviour that is specified.

Here 'a' is an identifier. Consider the following 12 expressions (I
use the word loosely).

1) a . b . c
2) (a . b) . c
3) a . (b . c)

4) a ?. b . c
5) (a ?. b) . c
6) a ?. (b . c)

7) a . b ?. c
8) (a . b) ?. c
9) a . (b ?. c)

10) a ?. b ?. c
11) (a .? b) ?. c
12) a ?. (b ?. c)

Question A: Which of the expressions are NOT valid (Python + PEP 505) syntax?
Question B: Which of the valid (Python + PEP 505) expressions are
equivalent, for all possible values of 'a'.

The answer depends, of course, on the exact text of PEP 505. I've not
read PEP 505 that closely. My expectations, based on my Python
experience, are that PEP 505 would be written so that:

Answer A: Expressions 3, 6, 9 and 12 are invalid. The others are valid.
Answer B: 1 and 2 are equivalent. Similarly 4 and 5. Similarly 7 and
8. Similarly 10 and 11. There are no other equivalences (for all
values of 'a').

I would like to know if my answers to my questions are correct, and if
not please may I be given correct answers. Thank you in advance.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-31 Thread MRAB

On 2018-07-31 20:53, Jonathan Fine wrote:

Stephan Houben wrote:


Nope, the introduction of the tmp variable changed the semantics. It isn't a
"chain" anymore so it breaks shortcutting.


I'm confused. Assume 'a' is not defined.

With Python's dot (attribute access) we have

a.b.c

NameError: name 'a' is not defined

a.(b.c)

SyntaxError: invalid syntax

(a.b).c

NameError: name 'a' is not defined

I'd expect, after PEP 505 is added to Python that we'd get

a ?. b ?. c

NameError: name 'a' is not defined

a ?. (b ?. c)

SyntaxError: invalid syntax

(a ? . b) ?. c

NameError: name 'a' is not defined

If this is not correct, please some do tell me what we would get.


Correct.


Now assume 'a' is defined. I'd also expect, for any value for 'a', that

tmp = (a ?. b)
val = tmp ?. c

give val the same value as

val = (a ?. b) ?. c


If this is not so, then can the second val be computed from tmp? And if so, how?


Also correct.

On the first point, Steven said that _figuratively speaking_ (his words) 
the series of attribute accesses would be _as though_ it was grouped 
a?.(b.c), so if a is None, then remainder of the attributes accessed 
would be short-circuited. He _wasn't_ suggesting that that was _actual_ 
syntax.


On the second point, you'd said:

tmp = spam ?. eggs
val2 = tmp . cheese . aardvark# For spam?.eggs.cheese.aardvark

i.e. that:

spam?.eggs.cheese.aardvark

could be rewritten as:

tmp = spam ?. eggs
val2 = tmp . cheese . aardvark

Steven pointed out that that was wrong.

In the first, if spam is None, then the remainder is short-circuited, 
and so the result of spam?.eggs.cheese.aardvark is None.


In the second, if spam is None, then tmp would be None, and tmp.cheese 
would fail.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-31 Thread Jonathan Fine
Stephan Houben wrote:

> Nope, the introduction of the tmp variable changed the semantics. It isn't a
> "chain" anymore so it breaks shortcutting.

I'm confused. Assume 'a' is not defined.

With Python's dot (attribute access) we have
>>> a.b.c
NameError: name 'a' is not defined
>>> a.(b.c)
SyntaxError: invalid syntax
>>> (a.b).c
NameError: name 'a' is not defined

I'd expect, after PEP 505 is added to Python that we'd get
>>> a ?. b ?. c
NameError: name 'a' is not defined
>>> a ?. (b ?. c)
SyntaxError: invalid syntax
>>> (a ? . b) ?. c
NameError: name 'a' is not defined

If this is not correct, please some do tell me what we would get.

Now assume 'a' is defined. I'd also expect, for any value for 'a', that
>>> tmp = (a ?. b)
>>> val = tmp ?. c
give val the same value as
>>> val = (a ?. b) ?. c

If this is not so, then can the second val be computed from tmp? And if so, how?

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-31 Thread Steven D'Aprano
On Tue, Jul 31, 2018 at 02:14:19PM -0400, David Mertz wrote:
> On Tue, Jul 31, 2018, 1:47 PM Steven D'Aprano  wrote:
> 
> > Yes it is. Rhodri is correct, although I admit that I hadn't realised
> > this point myself until he pointed it out. (That is why until now I've
> > been writing examples like "spam?.eggs?.cheese?.aardvark" which is
> > redundant.)
> >
> 
> Again, one of the most vocal advocates of the PEP gets the semantics wrong!
> 
> `spam?.eggs?.cheese?.aardvark` is NOT redundant for `
> spam?.eggs.cheese.aardvark`.

It is if *only* spam can be None, which is the scenario being discussed.

Please don't ignore the context of statements. I didn't say that

spam?.eggs.cheese.aardvark

would guard against eggs or cheese being None. That interpretation of my 
comment is uncharitable and not supported by my re-write of the 
pseudo-code from the PEP.

It also goes completely against my comment "Figuratively speaking..." 
that the ?. operator groups to the right:

spam?(.eggs.cheese.aardvark)  # grouping, not function call.

Perhaps you didn't read my post all the way to the end before firing off 
a triumphant post accusing me of getting it wrong.

In context, the question is whether:

spam?.eggs.cheese.aardvark

might attempt to evaluate None.cheese.aardvark. It won't.

In context, the issue was not whether these two expressions are 
identical in every imaginable way:

spam?.eggs.cheese.aardvark

spam?.eggs?.cheese?.aardvark

In pseudo-code, they would be something close to:

if spam is not None:
return spam.eggs.cheese.aardvark

versus

if spam is not None:
if spam.eggs is not None:
if spam.eggs.cheese is not None:
return spam.eggs.cheese.aardvark

except without needing to evaluate each subexpression multiple times.

In context, we are discussing the behaviour when spam is None. When spam 
is None, there's no need for the additional maybe-dots, because the 
first short-circuits the rest. If additional attributes also could be 
None, then they too could be guarded with maybe-dot operators, but if 
they are never None, it is unnecessary and redundant to guard spam alone 
all the way through the expression with maybe-dots.


> The two expressions simply do different
> things, but in a way guaranteed to assure that also everyone gets the
> actual behaviors wrong.

Putting aside your prejudicial language about guaranteeing errors, I 
think that the PEP could be improved. I managed to read it multiple 
times without taking in the fact that ?. short-circuits to the right. I 
didn't explicitly say so (perhaps I should have) but I too initially 
made the same error as Abe, assuming that

spam?.eggs.cheese

would fail if spam was None (evaluating None.cheese) but according to 
the PEP that's not the case.

With a working implementation, it would be the work of moments for
people to experiment in the REPL and clarify any lingering doubts about 
the operation.

Without it, there will always be some misunderstandings from those who 
(like me) failed to read the documentation carefully enough and made 
upjustified assumptions. That's no different from any other non-trivial 
feature.


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-31 Thread Stephan Houben
Op di 31 jul. 2018 20:49 schreef Jonathan Fine :

> David Mertz wrote:
>
> > `spam?.eggs?.cheese?.aardvark` is NOT redundant for
> > `spam?.eggs.cheese.aardvark`.  The two expressions simply do different
> > things [...]
>
> I agree, assuming ?. is a binary operator.


It isn't.


Given this, in Python (+
> PEP 505) one can write
>
> tmp = spam ?. eggs
> val1 = tmp ?. cheese ?. aardvark# For spam?.eggs?.cheese?.aardvark
> val2 = tmp . cheese . aardvark# For spam?.eggs.cheese.aardvark
>

Nope, the introduction of the tmp variable changed the semantics. It isn't
a "chain" anymore so it breaks shortcutting.

To be honest I didn't get this either until it was pointed out to me

>
> No special knowledge of PEP 505 is needed. If val1 is always equal to
> val2, then the dot and None-dot operators must be the same. From the
> assumptions, this is something that can be mathematically proved.
>

And false.


> By the way, there's a widely used programming language in which
> val = a.method()
> and
> tmp = a.method
> val = tmp()
> are not always equivalent. Can you guess which language it is?


Javascript.
I suppose in the same way as x+2 and x*2 are " not always" equivalent.

Stephan



> The answer is in:
>
> https://www.slideshare.net/jonathanfine/javascript-the-easiest-quiz-in-the-world-ever
> (question 6: Dot binds).
>
> I'll now go back to following the example of Steve Bower and Raymond
> Hettinger, which in my words is to wait until we have proper cover for
> the BDFL's vacation.
>
> --
> Jonathan
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-31 Thread Jonathan Fine
David Mertz wrote:

> `spam?.eggs?.cheese?.aardvark` is NOT redundant for
> `spam?.eggs.cheese.aardvark`.  The two expressions simply do different
> things [...]

I agree, assuming ?. is a binary operator.  Given this, in Python (+
PEP 505) one can write

tmp = spam ?. eggs
val1 = tmp ?. cheese ?. aardvark# For spam?.eggs?.cheese?.aardvark
val2 = tmp . cheese . aardvark# For spam?.eggs.cheese.aardvark

No special knowledge of PEP 505 is needed. If val1 is always equal to
val2, then the dot and None-dot operators must be the same. From the
assumptions, this is something that can be mathematically proved.

By the way, there's a widely used programming language in which
val = a.method()
and
tmp = a.method
val = tmp()
are not always equivalent. Can you guess which language it is?

The answer is in:
https://www.slideshare.net/jonathanfine/javascript-the-easiest-quiz-in-the-world-ever
(question 6: Dot binds).

I'll now go back to following the example of Steve Bower and Raymond
Hettinger, which in my words is to wait until we have proper cover for
the BDFL's vacation.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-31 Thread Rhodri James

On 31/07/18 18:46, Steven D'Aprano wrote:

n Mon, Jul 30, 2018 at 12:41:20PM -0500, Abe Dillon wrote:

[Rhodri James]

On 29/07/18 16:12, Abe Dillon wrote:
  > spam?.eggs.cheese.aardvark  # why would you ever do this?

If you knew that if you really have something in "spam", your program
guarantees it will have an "eggs" attribute with a "cheese" attribute, etc,
you just don't know if "spam" is not None.  It's the same insider knowledge
you would use if you wrote it out as

spam.eggs.cheese.aardvark if spam is not None else None


That's not the equivalent as described in PEP 505.

Yes it is. Rhodri is correct, although I admit that I hadn't realised
this point myself until he pointed it out. (That is why until now I've
been writing examples like "spam?.eggs?.cheese?.aardvark" which is
redundant.)


Doh!  Yes, of course, the point was it was short-circuiting.  This keeps 
confusing me (easily done, I'll admit), which is probably not a point in 
its favour.


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-31 Thread David Mertz
On Tue, Jul 31, 2018, 1:47 PM Steven D'Aprano  wrote:

> Yes it is. Rhodri is correct, although I admit that I hadn't realised
> this point myself until he pointed it out. (That is why until now I've
> been writing examples like "spam?.eggs?.cheese?.aardvark" which is
> redundant.)
>

Again, one of the most vocal advocates of the PEP gets the semantics wrong!

`spam?.eggs?.cheese?.aardvark` is NOT redundant for `
spam?.eggs.cheese.aardvark`.  The two expressions simply do different
things, but in a way guaranteed to assure that also everyone gets the
actual behaviors wrong.

Hint, run this before each expression:

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-31 Thread Steven D'Aprano
On Mon, Jul 30, 2018 at 12:41:20PM -0500, Abe Dillon wrote:

[Rhodri James]
> > On 29/07/18 16:12, Abe Dillon wrote:
> >  > spam?.eggs.cheese.aardvark  # why would you ever do this?
> > 
> > If you knew that if you really have something in "spam", your program
> > guarantees it will have an "eggs" attribute with a "cheese" attribute, etc,
> > you just don't know if "spam" is not None.  It's the same insider knowledge
> > you would use if you wrote it out as
> > 
> > spam.eggs.cheese.aardvark if spam is not None else None
> 
> 
> That's not the equivalent as described in PEP 505. 

Yes it is. Rhodri is correct, although I admit that I hadn't realised 
this point myself until he pointed it out. (That is why until now I've 
been writing examples like "spam?.eggs?.cheese?.aardvark" which is 
redundant.)

The abstract says:

The "None-aware attribute access" operator ?. ("maybe dot")
evaluates the complete expression if the left hand side 
evaluates to a value that is not None

and later on the PEP says:

When a None-aware operator is present, the left-to-right 
evaluation may be short-circuited. For example, 
await a?.b(c).d?[e] is evaluated:

_v = a
if _v is not None:
_v = _v.b
_v = _v(c)
_v = _v.d
if _v is not None:
_v = _v[e]
await _v


I admit the example isn't the clearest. The inclusion of "await" doesn't 
seem helpful to me (if anything, the opposite, since "await None" will 
fail) and perhaps it would be clearer to write it as:

_v = a
if _v is not None:
_v = _v.b(c).d
if _v is not None:
_v = _v[e]


The PEP also says:

Parenthesised expressions are handled by the atom rule (not 
shown above), which will implicitly terminate the short-
circuiting behaviour of the above transformation.

which again isn't too clear, and the example given seems complicated 
enough to obfuscate the point rather than illustrate it, but if I'm 
reading it correctly, the behaviour you expected would have to be 
written as

(spam?.eggs).cheese.aardvark

which would likely fail since None has no cheese attribute.

The bottom line is that in any unparenthesized chain of maybe-dot and 
maybe-subscript operations, only the first needs to be "maybe" as that 
will short-circuit the rest of the expression.

Figuratively speaking, it is as if we had:

spam?(.eggs.cheese.aardvark)

where the () are used for grouping, not function call.



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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-30 Thread Abe Dillon
 [Rhodri James]

> We could argue about how intuitive or not these operators are, but they
>>> are used in other languages, so they clearly aren't completely
>>> unintuitive.
>>>
>>
>> Other languages are other languages. Other languages use the "
>> ?
>>  : " form of the the ternary operator. That doesn't mean
>> we
>> should adopt that into Python.
>>
>
> But it does and did mean that we should consider it when coming up with
> Python's version of the ternary operator.  *It isn't unintuitive* and
> neither is ??  None-aware operators may be bad for other reasons, but that
> argument doesn't wash.


No. The fact that other languages use it doesn't mean that "it isn't
unintuitive". The fact that other languages use it doesn't mean that it
doesn't harm readability. The fact that other languages use it has pretty
much no bearing on any of that. What it actually means is: other languages
are trying it out so we have the luxury of seeing if they regret it in the
future or if it becomes a popular and well loved feature before integrating
it into Python.

I believe it's counter-intuitive because '?' always comes at the end of an
english sentence, so it reads like other clause-ending operators like the
")" on a function call or the "]" at the end of a index operation, then the
"." reads like a follow-on.

And no; you can't say the same thing about "." always coming at the end of
a sentence because:

a) that's not true (e.g. i.e, e.g., etc.)

b) "." attribute access has many decades of precedence

c) a "." is less visually obtrusive than a "?".

[Rhodri James]

>  Pardon?  It composes exactly like any other in-place operator.


Yes. I'll concede. I was wrong about that.

[Rhodri James]

> yes, you do need to explain how merely being high precedence helps here.
> Let's start small; please explain programmatically what


>   name?



does as an expression.  Once we have that down, we can move on to



  person.(name?)


Sure. First, I would suggest we define a new class
NoneException(BaseException), and derive new Exception multi-classes like:
class NoneAttributeError(AttributeError, NoneException).
Then I would make those the exceptions thrown by attribute errors on the
None object. That way you can conceptualize the '?' operator is to the
try-except statement as the ternary operator is to if-else statements
EXCEPT that the "except" part of the try-except block is implicitly filled
in with "except NoneException: return None" so in general:

?

Would parse to:

try:
result = eval(expression)
except NoneException:
result = None

Similar to how:

 if  else 

Parses to:

if eval(condition_expression):
result = eval(expression_1)
else:
result = eval(expression_2)

More specifically:

name?

Wouldn't do much:

try:
result = name
except NoneException:
result = None

And:

person.(name?)

would throw a SyntaxError because person.( is not valid syntax regardless
of my proposal.
Perhaps you meant something like:

(person.name).first?

In that case; person.name would evaluate to some result or throw an
un-guarded AttributeError, in the former case the  to the left
of the '?' is an attribute access on the result of (person.name). In the
latter case; an AttributeError is thrown.

That seems pretty straight forward. No?

On 29/07/18 16:12, Abe Dillon wrote:

>  > spam?.eggs.cheese.aardvark  # why would you ever do this?



> If you knew that if you really have something in "spam", your program
> guarantees it will have an "eggs" attribute with a "cheese" attribute, etc,
> you just don't know if "spam" is not None.  It's the same insider knowledge
> you would use if you wrote it out as




> spam.eggs.cheese.aardvark if spam is not None else None


That's not the equivalent as described in PEP 505. If "spam" is None,
"spam?.eggs" evaluates to None without throwing an AttributeError, but the
rest of the expression will throw an AttributeError from trying to access
"None.cheese".

On Mon, Jul 30, 2018 at 9:10 AM, Rhodri James  wrote:

> On 29/07/18 16:12, Abe Dillon wrote:
>
>> spam?.eggs.cheese.aardvark  # why would you ever do this?
>>
>
> If you knew that if you really have something in "spam", your program
> guarantees it will have an "eggs" attribute with a "cheese" attribute, etc,
> you just don't know if "spam" is not None.  It's the same insider knowledge
> you would use if you wrote it out as
>
> spam.eggs.cheese.aardvark if spam is not None else None
>
> The same sort of knowledge of your program structure could lead to you to
> use "?." instead of "." in any place or places in the chain.  If your
> program gives you strong enough guarantees, it is the sort of thing you can
> use to reduce the code's workload.
>
> By way of example, I was working on some C code last night that was
> expanding an internal buffer, possibly from non-existence.  It did lot of
> taking the difference between various pointers to determine how big the new
> buffer needed to be, how much to copy from the old buffer, etc. 

Re: [Python-ideas] PEP 505: None-aware operators

2018-07-30 Thread Rhodri James

On 29/07/18 16:12, Abe Dillon wrote:

spam?.eggs.cheese.aardvark  # why would you ever do this?


If you knew that if you really have something in "spam", your program 
guarantees it will have an "eggs" attribute with a "cheese" attribute, 
etc, you just don't know if "spam" is not None.  It's the same insider 
knowledge you would use if you wrote it out as


spam.eggs.cheese.aardvark if spam is not None else None

The same sort of knowledge of your program structure could lead to you 
to use "?." instead of "." in any place or places in the chain.  If your 
program gives you strong enough guarantees, it is the sort of thing you 
can use to reduce the code's workload.


By way of example, I was working on some C code last night that was 
expanding an internal buffer, possibly from non-existence.  It did lot 
of taking the difference between various pointers to determine how big 
the new buffer needed to be, how much to copy from the old buffer, etc. 
It looked rather hairy until you realised that the code gave a strong 
guarantee that either all the pointers were meaningful or they were all 
NULL, so the pointer differences always made sense.  I rewrote that code 
so that it didn't take differences of NULL pointers since that was what 
the bug specified, but honestly it looks lumpier and less clear now.  A 
big comment explaining what was going on would probably be better.


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-30 Thread Rhodri James

On 28/07/18 21:07, Abe Dillon wrote:
[>> = Me]

We could argue about how intuitive or not these operators are, but they
are used in other languages, so they clearly aren't completely unintuitive.


Other languages are other languages. Other languages use the " ?
 : " form of the the ternary operator. That doesn't mean we
should adopt that into Python.


But it does and did mean that we should consider it when coming up with 
Python's version of the ternary operator.  *It isn't unintuitive* and 
neither is ??  None-aware operators may be bad for other reasons, but 
that argument doesn't wash.



Really?  Quick straw poll: how often do people care how in-place operators
are implemented?


The point I was trying to make is that it doesn't behave or compose like
other expressions.


(This was about ??=, for context.)  Pardon?  It composes exactly like 
any other in-place operator.


[Abe previously wrote:]
>>> val = person[0]?
>>> val = person.name?
>>

Um.  How is that supposed to parse?  "person[0]" has already been evaluated
by the time the "?" operator gets anywhere near it.


It parses by placing the '?' operator high in the order of operations; like
I said. Do I really need to explain how order of operations works?


Apology elsewhere accepted, but yes, you do need to explain how merely 
being high precedence helps here.  Let's start small; please explain 
programmatically what


  name?

does as an expression.  Once we have that down, we can move on to

  person.(name?)

(parentheses for emphasis.)  Short of actual magic, I can't see how this 
is going to work.


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-29 Thread Nicholas Chammas
On Sun, Jul 29, 2018 at 10:58 AM Steven D'Aprano 
wrote:

> On Sun, Jul 29, 2018 at 06:32:19AM -0400, David Mertz wrote:
> > On Sun, Jul 29, 2018, 2:00 AM Steven D'Aprano 
> wrote:
> >
> > > Fine. So it takes them an extra day to learn one more operator. Big
> > > deal. It is commonly believed to take ten years to master a field or
> > > language. Amortize that one day over ten years and its virtually
> > > nothing.
> > >
> >
> > This is where being wrong matters. The experience in this thread of most
> > supporters failing to get the semantics right shows that this isn't an
> > extra day to learn.
>
> The difficulty one or two people had in coming up with a correct
> equivalent to none-aware operators on the spur of the moment is simply
> not relevant. Aside from whichever developers implements the feature,
> the rest of us merely *use* it, just as we already use import,
> comprehensions, yield from, operators, class inheritence, and other
> features which are exceedingly difficult to emulate precisely in pure
> Python code.
>
> Even something as simple as the regular dot attribute lookup is
> difficult to emulate precisely. I doubt most people would be able to
> write a pure-Python version of getattr correctly the first time. Or even
> the fifth. I know I wouldn't.
>
> I'm sure that you are fully aware that if this proposal is accepted,
> people will not need to reinvent the wheel by emulating these none-aware
> operators in pure Python, so your repeated argument that (allegedly)
> even the supporters can't implement it correctly is pure FUD. They won't
> have to implement it, that's the point.


+1 to this, though I agree with Raymond's post that perhaps a breather on
language changes would be helpful until some of the recently introduced
features have become more familiar to folks.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-29 Thread Abe Dillon
[Chris Angelico]

> Almost. Except for the problem that "disgusting" is a subjective term.


Yes. Thank you for explaining the joke.

 [Brice Parent]

> I don't believe we need spam.eggs.cheese.aardvark? (there is exactly the
> same number of use cases). We win a bit in readability as it's closer to
> most spoken languages, but we lose in granularity as we're hiding any error
> that would raise if spam.eggs returned None, so it's not a full win on
> this side either...


First, I mostly proposed that alternative to serve my argument that there
may be a better syntax that PEP 505 would make impossible down the road.
It's a half-baked proposal at best and I agree with your over-all sentiment
that it's probably not something we should consider either. That being
said; in the normal usage of '?.' and '?[]' it would make little sense to
only check the beginning of the expression:

spam?.eggs.cheese.aardvark  # why would you ever do this?

It makes some sense to do this:

spam.eggs.cheese?.aardvark

But in my proposal, you could force any part of the expression to evaluate
before the '?' with parentheses and expose whatever errors that might throw:

(spam.eggs.cheese).aardvark?

On Sun, Jul 29, 2018 at 7:15 AM, Chris Angelico  wrote:

> On Sun, Jul 29, 2018 at 8:32 PM, David Mertz  wrote:
> > I can hardly imagine a stronger bug magnet than PEP 505.
>
> The hyperbole in this thread is impressive. Not just "I can hardly
> imagine anyone PROPOSING a stronger bug magnet". You cannot imagine
> one even existing.
>
> And this is after people have proposed that "if x = 1:" become the
> spelling for assignment expressions - something so well known as a bug
> magnet that C compilers specifically warn against it, and style guides
> recommend always writing "if (1 == x)" instead. Claiming that "?." is
> *the worst possible bug magnet* rather weakens your credibility here.
>
> ChrisA
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-29 Thread Steven D'Aprano
On Sun, Jul 29, 2018 at 06:32:19AM -0400, David Mertz wrote:
> On Sun, Jul 29, 2018, 2:00 AM Steven D'Aprano  wrote:
> 
> > Fine. So it takes them an extra day to learn one more operator. Big
> > deal. It is commonly believed to take ten years to master a field or
> > language. Amortize that one day over ten years and its virtually
> > nothing.
> >
> 
> This is where being wrong matters. The experience in this thread of most
> supporters failing to get the semantics right shows that this isn't an
> extra day to learn.

The difficulty one or two people had in coming up with a correct 
equivalent to none-aware operators on the spur of the moment is simply 
not relevant. Aside from whichever developers implements the feature, 
the rest of us merely *use* it, just as we already use import, 
comprehensions, yield from, operators, class inheritence, and other 
features which are exceedingly difficult to emulate precisely in pure 
Python code.

Even something as simple as the regular dot attribute lookup is 
difficult to emulate precisely. I doubt most people would be able to 
write a pure-Python version of getattr correctly the first time. Or even 
the fifth. I know I wouldn't.

I'm sure that you are fully aware that if this proposal is accepted, 
people will not need to reinvent the wheel by emulating these none-aware 
operators in pure Python, so your repeated argument that (allegedly) 
even the supporters can't implement it correctly is pure FUD. They won't 
have to implement it, that's the point.


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-29 Thread Chris Angelico
On Sun, Jul 29, 2018 at 8:32 PM, David Mertz  wrote:
> I can hardly imagine a stronger bug magnet than PEP 505.

The hyperbole in this thread is impressive. Not just "I can hardly
imagine anyone PROPOSING a stronger bug magnet". You cannot imagine
one even existing.

And this is after people have proposed that "if x = 1:" become the
spelling for assignment expressions - something so well known as a bug
magnet that C compilers specifically warn against it, and style guides
recommend always writing "if (1 == x)" instead. Claiming that "?." is
*the worst possible bug magnet* rather weakens your credibility here.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-29 Thread Brice Parent

Le 29/07/2018 à 09:12, Abe Dillon a écrit :




[...]


NO! I'm proposing:

spam.eggs.cheese.aardvark?

A single POSTFIX operator that has a high priority in the order of 
operations.
I don't believe we need spam?.eggs.cheese?.aardvark, because I don't 
think it is justified by the small benefits it gets us.
For the same reason, I don't believe we need spam.eggs.cheese.aardvark? 
(there is exactly the same number of use cases). We win a bit in 
readability as it's closer to most spoken languages, but we lose in 
granularity as we're hiding any error that would raise if spam.eggs 
returned None, so it's not a full win on this side either...


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-29 Thread Brice Parent

Le 29/07/2018 à 08:02, Steven D'Aprano a écrit :

On Sun, Jul 29, 2018 at 12:49:13PM +1200, Greg Ewing wrote:

Abe Dillon wrote:

others countering that `person.name ` is not how
periods are used in natural languages, so using other symbols in
unintuitive ways is perfectly fine.

Dots have been used for attribute access in so many languages
for so long that it has become the normal and expected syntax
to use. ?. is much more recent. Maybe in another 30 years, if
it has stood the test of time, it could be argued for on the
basis of familiarity, but not now.

You're talking like the syntax is used only by a handful of experimental
languages with a total user-base measured in the dozens.

?. is used by some of the most commonly used languages in the world,
such as C++, Objective C and PHP, as well as up-and-coming "cool"
languages getting lots of industry buzz, like Swift and Dart.

Its certainly more familiar now than Python's slicing syntax was when
Python first started.
But it's certainly less familiar than using 'foo++' and '++foo', but 
we're still writing 'foo += 1'. So familiarity in other languages is not 
the only point (alos, I'm convinced that if we were making a poll with 
average and advanced users of these languages about what these syntax 
were doing, a big proportion wouldn't know).


I believe the evolution should be done if the benefice are big enough 
(which I doubt, but I don't use Python in all the ways possible), not 
because others do it (whatever their reasons were). Then, when we know 
there's definitely a need to solve a problem, the solution should be 
chosen (??, but anything else could enter the discussion).


Here, we're mixing arguments about (and I confess I've done it too):
- how usefull it would be to have a solution to this problem
- if it should be solved by Python's syntax or by libraries (if it may 
be done, and if it may not, how spread are the use cases that can't be 
done this way)
- if other languages support something like that, if some are, how well 
this was accepted and if it's getting used in new code

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-29 Thread David Mertz
On Sun, Jul 29, 2018, 2:00 AM Steven D'Aprano  wrote:

> Fine. So it takes them an extra day to learn one more operator. Big
> deal. It is commonly believed to take ten years to master a field or
> language. Amortize that one day over ten years and its virtually
> nothing.
>

This is where being wrong matters. The experience in this thread of most
supporters failing to get the semantics right shows that this isn't an
extra day to learn. It's something that experienced programmers would
continue to get won't in edge cases after years of use. The proposed
operators don't match how most experienced developers think about code.

Being glaringly ugly as written, and using an unintuitive or
counterintuitive symbol alternates that, of course.

I can hardly imagine a stronger bug magnet than PEP 505.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-29 Thread Chris Angelico
On Sun, Jul 29, 2018 at 5:12 PM, Abe Dillon  wrote:
> The syntax of this proposal is almost objectively disgusting. It's truly
> horrid. I don't know how many ways to say it.

Almost. Except for the problem that "disgusting" is a subjective term.
If you want to say that this is *objectively disgusting*, you're going
to need some actual justification.

If you just mean "I find this disgusting", then that's fine, but we
already heard that argument. It's a statement of opinion, not of fact.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-29 Thread Abe Dillon
First of all: Thanks to everyone for explaining everything about the id
function.
You are all so smart...

[Greg Ewing]

> Dots have been used for attribute access in so many languages
> for so long that it has become the normal and expected syntax
> to use. ?. is much more recent. Maybe in another 30 years, if
> it has stood the test of time, it could be argued for on the
> basis of familiarity, but not now.


My point exactly.

[Steve D'Aprano]

> You're thinking of Scratch and other languages aimed at school kids.


Nope. I'm thinking of Python.

[Steve D'Aprano]

> frankly I'm getting sick to the back teeth of
> people saying "Mustn't do that useful thing because it will make Python
> harder for beginners to learn".


> Fine. So it takes them an extra day to learn one more operator. Big
> deal.


It's not just about learning it. It's about the mental load of reading
code. little things add up.

If "sick through your back teeth" of people being cautious, that sounds
like a personal problem. I'm worried about the pace people are adding
functionality to Python. You start learning about concurrent.futures, then
asyncio gets added with "yield from", then async def and await and all that
gets added and it all seems to be a mess. Now there are how many ways to
format strings?

Should we just shovel features from other popular languages into Python
because they might be a little useful? I wouldn't wan't your back teeth to
rot from my prudishness...

Python is very little like natural language. Your earlier idea that
> attribute access spam.eggs is like natural language (in English) because
> its only a few characters different from "spam's eggs" really doesn't
> hold up. Apart from the word order, there's no similarity.


I feel like you're being willfully dense about this. There is a difference
between:

if any(thing.is_metalic for thing in pockets): raise Alarm("metal
> detected!")


and

if any(thing$!<>~.s_metal for thing in pockets): raise Alarm("metal
> detected!")


The syntax of this proposal is almost objectively disgusting. It's truly
horrid. I don't know how many ways to say it.

[Steve D'Aprano]

> I don't know that Python has any binary operators which are split
> into an infix part and a postfix part.


That's not at all what I proposed.

[Steve D'Aprano]

> So you're against:
> spam?.eggs?.cheese?.aardvark
> but you prefer:
> spam.eggs?.cheese?.aardvark?
> instead.


NO! I'm proposing:

spam.eggs.cheese.aardvark?

A single POSTFIX operator that has a high priority in the order of
operations.


On Sun, Jul 29, 2018 at 1:03 AM, Chris Angelico  wrote:

> On Sun, Jul 29, 2018 at 3:54 PM, Steven D'Aprano 
> wrote:
> > Being an implementation detail, CPython is free to change it at any
> > time, without warning or notice, even in a bug-fix release. If CPython
> > ever gets a memory manager that can move objects around, as they can
> > move in Jython and IronPython, CPython will also have to change id().
> >
>
> To clarify: If that were to happen, CPython would change *the
> description of the id() function*, not the IDs returned. The IDs
> returned must be constant for the lifetime of the object, as that's
> what Python-the-language demands and guarantees.
>
> ChrisA
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-29 Thread Chris Angelico
On Sun, Jul 29, 2018 at 3:54 PM, Steven D'Aprano  wrote:
> Being an implementation detail, CPython is free to change it at any
> time, without warning or notice, even in a bug-fix release. If CPython
> ever gets a memory manager that can move objects around, as they can
> move in Jython and IronPython, CPython will also have to change id().
>

To clarify: If that were to happen, CPython would change *the
description of the id() function*, not the IDs returned. The IDs
returned must be constant for the lifetime of the object, as that's
what Python-the-language demands and guarantees.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-29 Thread Steven D'Aprano
On Sun, Jul 29, 2018 at 12:49:13PM +1200, Greg Ewing wrote:
> Abe Dillon wrote:
> >others countering that `person.name ` is not how 
> >periods are used in natural languages, so using other symbols in 
> >unintuitive ways is perfectly fine.
> 
> Dots have been used for attribute access in so many languages
> for so long that it has become the normal and expected syntax
> to use. ?. is much more recent. Maybe in another 30 years, if
> it has stood the test of time, it could be argued for on the
> basis of familiarity, but not now.

You're talking like the syntax is used only by a handful of experimental 
languages with a total user-base measured in the dozens.

?. is used by some of the most commonly used languages in the world, 
such as C++, Objective C and PHP, as well as up-and-coming "cool" 
languages getting lots of industry buzz, like Swift and Dart.

Its certainly more familiar now than Python's slicing syntax was when 
Python first started.



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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-29 Thread Steven D'Aprano
On Sat, Jul 28, 2018 at 10:56:13PM -0500, Abe Dillon wrote:
> >
> > Python does not have memory locations.
> >
> 
> CPython does, form the documentation on the `id` function:

No, that is the same id() function as the id() provided by Jython, and 
IronPython, and Stackless. Like all Python implementations, it returns 
an opaque integer ID number.

That's why it is called "id" rather than "memory_location" or "address".


> *CPython implementation detail:* This is the address of the object in
> > memory.

An irrelevant implementation detail. You can't use the id() as a memory 
address, and even if you could, that wouldn't be portable Python code, 
it would be an implementation-dependent hack that is unsafe or 
unreliable to use.

Being an implementation detail, CPython is free to change it at any 
time, without warning or notice, even in a bug-fix release. If CPython 
ever gets a memory manager that can move objects around, as they can 
move in Jython and IronPython, CPython will also have to change id().

id() may, sometimes, *use* the memory address, but the semantics are 
not that of a memory address.


> I'm not sure what performance implications there would be for adding a
> __none_check__ or whatever method to None.

The point of testing for None is because you want None, and absolutely 
no other object but None. A __none_check__ method would allow other 
objects to lie about being None-like. The point of using "is" is to 
avoid that.

If you want any arbitrary object which happens to be a bit None-like, 
then call "x == None" and let x decide for itself. But be prepared to 
have experienced Python programmers correct your "mistake" unless you 
carefully document why you are doing this.


> Python is supposed to emphasize readability and learnability.

You're thinking of Scratch and other languages aimed at school kids.

Python emphasizes many things. Its not merely a kiddies' language, or a 
beginners' language, or an educational language. It is a language used 
by professionals, and frankly I'm getting sick to the back teeth of 
people saying "Mustn't do that useful thing because it will make Python 
harder for beginners to learn".

Fine. So it takes them an extra day to learn one more operator. Big 
deal. It is commonly believed to take ten years to master a field or 
language. Amortize that one day over ten years and its virtually 
nothing.


> To that end, expressions should strive to resemble natural language.

If you want a programming language that looks like natural language, you 
want something like Hypertalk:

  put the second word of field "Address" after line 3 of field "Record"

or Inform7. Or the granddaddy of "natural language" programming, COBOL.

Python is very little like natural language. Your earlier idea that 
attribute access spam.eggs is like natural language (in English) because 
its only a few characters different from "spam's eggs" really doesn't 
hold up. Apart from the word order, there's no similarity.


> Otherwise they should try to resemble common mathematical notation. Failing
> that, they should try to resemble common programming idioms.

Yes, common programming idioms like null-coalescing and null-aware 
operators, which are used by a good half dozen popular, modern 
languages.


> "?." doesn't resemble anything in natural language.

That's okay. Neither does spam.eggs, or spam[eggs], or anything to do 
with async, or function call notation func(a, b, c, keyword=d).


> It's not hard to check for None with a ternary statement. 

You're thinking in terms of trivial cases like 

default if x is None else x

but replace x with a long, potentially expensive expression and 
you may think differently:

default if spam(a, b, c, kw=d).eggs[cheese]() is None else spam(a, b c, 
kw=d).eggs[cheese]()

or a chain of tests:

if spam(a, b, c, kw=d) is not None:
if spam(a, b, c, kw=d).eggs is not None:
if spam(a, b, c, kw=d).eggs[cheese] is not None:
result = spam(a, b, kw=d).eggs[cheese]()


> Adding a '?'
> operator that goes at the end of an expression could do the same thing more
> elegantly 

I don't know that Python has any binary operators which are split 
into an infix part and a postfix part. I don't know any language with an 
operator like that. There is the ternary operator, of course, but this 
would be a binary operator.

So you're against:

spam?.eggs?.cheese?.aardvark

but you prefer:

spam.eggs?.cheese?.aardvark?

instead.



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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-28 Thread Greg Ewing

Abe Dillon wrote:
others countering that `person.name ` is not how 
periods are used in natural languages, so using other symbols in 
unintuitive ways is perfectly fine.


Dots have been used for attribute access in so many languages
for so long that it has become the normal and expected syntax
to use. ?. is much more recent. Maybe in another 30 years, if
it has stood the test of time, it could be argued for on the
basis of familiarity, but not now.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-28 Thread Chris Angelico
On Sun, Jul 29, 2018 at 1:56 PM, Abe Dillon  wrote:
>> Python does not have memory locations.
>
>
> CPython does, form the documentation on the `id` function:
>
>> CPython implementation detail: This is the address of the object in
>> memory.

Right, which is an important distinction; CPython, being a concrete
implementation, does involve memory. For instance, you can ask "how
many bytes of memory does this object take up?" and CPython can answer
that (sys.getsizeof). You can't ask that in Python generally, because
the abstract language doesn't have memory or any such concept.

The "None" object exists in the abstract sense. It will be present in
ANY Python implementation. In theory, a Python could use a null
pointer to represent None, just as long as you can't tell the
difference between that behaviour and any other.

> I'm not sure what performance implications there would be for adding a
> __none_check__ or whatever method to None.

Considering that None is a singleton, there's no need to create a
protocol for asking "are you None?". The obvious way to say "are you
None?" is to inquire if some object and None are the same object,
which is spelled "x is None".

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-28 Thread Abe Dillon
>
> Python does not have memory locations.
>

CPython does, form the documentation on the `id` function:

*CPython implementation detail:* This is the address of the object in
> memory.


I'm not sure what performance implications there would be for adding a
__none_check__ or whatever method to None.

None *is* an actual object. It
> has attributes, it has standard behaviours, it fits in the same object
> model as everything else in Python does.


 Cool. Thanks for the info. I wasn't sure because it's considered un-kosher
(according to PyCharm) to use "if x == None:" instead of "if x is None".

This is utter nonsense on par with trying to claim that "x <= y"
> should be parsed as if it's a modified form of assignment since "x =
> y" would be assignment.


This is getting tedious. It's only comparable to '<=' if you disregard
every other point I've made.
Python is supposed to emphasize readability and learnability. To that end,
expressions should strive to resemble natural language.
Otherwise they should try to resemble common mathematical notation. Failing
that, they should try to resemble common programming idioms.
There's no easy way to do subscripts, so we use square brackets for
indexing. That's a reasonable and pragmatic compromise.
`<=` is a fine compromise too because there's no easy way to type the ≤
symbol on most keyboards and it's a perfectly familiar symbol from
grade-school math.
Sure, someone could confuse '<=' for an assignment operator, I suppose; but
there's enough going for '<=' that it's easy to justify its existence for
pragmatism's sake.
The same can not be said for '?.'. It's not even remotely close to the same
thing.

"?." doesn't resemble anything in natural language. It doesn't resemble
anything in common mathematics. It isn't a well established pattern in
programming that has decades of precedent (like square bracket indexing).
It's not hard to check for None with a ternary statement. Adding a '?'
operator that goes at the end of an expression could do the same thing more
elegantly and resemble natural language at the same time. For all of those
reasons: I'm against this proposal.

Do I really need to explain how two-character operators work?


Point taken, I'll watch my tone. Rhodri James, I'm sorry for that flippant
remark about order of operations. It was uncalled for.

On Sat, Jul 28, 2018 at 3:14 PM, Chris Angelico  wrote:

> On Sun, Jul 29, 2018 at 6:07 AM, Abe Dillon  wrote:
> > Yes, I thought of that and came to the same conclusion. It's my
> > understanding that None may not be an actual object, but a special memory
> > location. I'm not sure though and didn't look it up.
>
> Python does not have memory locations. None *is* an actual object. It
> has attributes, it has standard behaviours, it fits in the same object
> model as everything else in Python does.
>
> >> As you said, "?" is not an operator, so "a?.b" clearly can't break down
> >> into "a? .b".
> >
> >
> > The problem is that '.' IS a stand-alone operator, so it's natural to
> > visually parse `.b` as `  .b`, but adding '?.' causes double
> > takes, more mental load, general interruption of the flow of reading. It
> > also sets up the later discussion of other possible uses of the '?'
> symbol
> > that may or may not have more merit.
>
> This is utter nonsense on par with trying to claim that "x <= y"
> should be parsed as if it's a modified form of assignment since "x =
> y" would be assignment.
>
> Do I really need to explain how two-character operators work?
>
> ChrisA
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-28 Thread Chris Angelico
On Sun, Jul 29, 2018 at 6:07 AM, Abe Dillon  wrote:
> Yes, I thought of that and came to the same conclusion. It's my
> understanding that None may not be an actual object, but a special memory
> location. I'm not sure though and didn't look it up.

Python does not have memory locations. None *is* an actual object. It
has attributes, it has standard behaviours, it fits in the same object
model as everything else in Python does.

>> As you said, "?" is not an operator, so "a?.b" clearly can't break down
>> into "a? .b".
>
>
> The problem is that '.' IS a stand-alone operator, so it's natural to
> visually parse `.b` as `  .b`, but adding '?.' causes double
> takes, more mental load, general interruption of the flow of reading. It
> also sets up the later discussion of other possible uses of the '?' symbol
> that may or may not have more merit.

This is utter nonsense on par with trying to claim that "x <= y"
should be parsed as if it's a modified form of assignment since "x =
y" would be assignment.

Do I really need to explain how two-character operators work?

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-28 Thread Abe Dillon
>
> We could argue about how intuitive or not these operators are, but they
> are used in other languages, so they clearly aren't completely unintuitive.


Other languages are other languages. Other languages use the " ?
 : " form of the the ternary operator. That doesn't mean we
should adopt that into Python.

Being visually obtrusive would help a great deal.  Unfortunately I don't
> think it is visually obtrusive in the ?. and ?[] operators.


My argument about visual obtrusiveness is in the context of me claiming
that python attempts to mimic natural language to achieve readability,
others countering that `person.name` is not how periods are used in natural
languages, so using other symbols in unintuitive ways is perfectly fine. My
point is that '.' is unobtrusive, so it's not *that* different from `person
name' which isn't *that* different from `person's name`. The '?' symbol is
most definitely more visually obtrusive than a simple '.' because it takes
up more space.

We could conceivably have a dunder method that None implemented as
> returning the other argument and object implemented as returning itself.
> I'm not really convinced that it's worth it, though.


Yes, I thought of that and came to the same conclusion. It's my
understanding that None may not be an actual object, but a special memory
location. I'm not sure though and didn't look it up.

Really?  Quick straw poll: how often do people care how in-place operators
> are implemented?


The point I was trying to make is that it doesn't behave or compose like
other expressions.

As you said, "?" is not an operator, so "a?.b" clearly can't break down
> into "a? .b".


The problem is that '.' IS a stand-alone operator, so it's natural to
visually parse `.b` as `  .b`, but adding '?.' causes double
takes, more mental load, general interruption of the flow of reading. It
also sets up the later discussion of other possible uses of the '?' symbol
that may or may not have more merit.

Um.  How is that supposed to parse?  "person[0]" has already been evaluated
> by the time the "?" operator gets anywhere near it.


It parses by placing the '?' operator high in the order of operations; like
I said. Do I really need to explain how order of operations works?

Why not indeed.  I haven't seen any convincing use cases (and nor has the
> PEP, though I doubt Steve was looking for them), but they aren't inherently
> any more weird than "?." and "?[]".


It seems like a natural extension. It also seems like a lot to add for
something as trivial as None handling.

While my immediate reaction is "yuk"


Is that more legit than my reaction to '?.' and '?[]'? At least in this
case, the '?' comes at the end of a clause...

your use of "?" does not conflict with any use in the PEP, so this is a red
> herring.


I suppose it doesn't *technically* conflict, but it would lead to some
beautiful code, like:

lambda data=a?.b?[0]?: data?.d

On Fri, Jul 27, 2018 at 7:00 AM, Rhodri James  wrote:

> On 26/07/18 22:28, Abe Dillon wrote:
>
>> The readability issue isn't just a matter of a new set of symbols to
>> learn.
>> It isn't even that the symbols are used in a non-intuitive way (though
>> that
>> doesn't help).
>>
>
> We could argue about how intuitive or not these operators are, but they
> are used in other languages, so they clearly aren't completely unintuitive.
>
> It's not even that the question mark, unlike the dot, is
>> very visually obtrusive (which also doesn't help).
>>
>
> Being visually obtrusive would help a great deal.  Unfortunately I don't
> think it is visually obtrusive in the ?. and ?[] operators.
>
> It also screws with the
>> grammar in an unexpected way. I would be fine with something like:
>>
>> def func(data=None):
>>  data ?= []
>>  ...
>>
>> If there were some corresponding dunder method to implement that behavior,
>> but it's not clear to me that such a thing is possible.
>>
>
> We could conceivably have a dunder method that None implemented as
> returning the other argument and object implemented as returning itself.
> I'm not really convinced that it's worth it, though.
>
> If it isn't, that
>> would make `?=` (or '??=' though I don't see the need for double '?'s)
>>
>
> Because it's the in-place version of "??", obviously.
>
> a
>> special statement, a special case that someone who's familiar with how
>> other in-place operators work, would be thrown for a loop.
>>
>
> Really?  Quick straw poll: how often do people care how in-place operators
> are implemented?
>
> The other use
>> cases look like they break down in a different manner than they actually
>> do:
>>
>> person?.name
>>
>> looks like it would break down similar to
>>
>> person().name
>>
>> but it doesn't because '?' by itself is not an operator.
>> similarly:
>>
>> person?[0]
>>
>> looks like it would break down similar to
>>
>> person()[0]
>>
>> but again, the operator is '?[...]' not '?'
>>
>
> Sorry, not buying this one.  As you said, "?" is not an operator, so
> 

Re: [Python-ideas] PEP 505: None-aware operators

2018-07-27 Thread Rhodri James

On 26/07/18 22:28, Abe Dillon wrote:

The readability issue isn't just a matter of a new set of symbols to learn.
It isn't even that the symbols are used in a non-intuitive way (though that
doesn't help).


We could argue about how intuitive or not these operators are, but they 
are used in other languages, so they clearly aren't completely unintuitive.



It's not even that the question mark, unlike the dot, is
very visually obtrusive (which also doesn't help).


Being visually obtrusive would help a great deal.  Unfortunately I don't 
think it is visually obtrusive in the ?. and ?[] operators.



It also screws with the
grammar in an unexpected way. I would be fine with something like:

def func(data=None):
 data ?= []
 ...

If there were some corresponding dunder method to implement that behavior,
but it's not clear to me that such a thing is possible.


We could conceivably have a dunder method that None implemented as 
returning the other argument and object implemented as returning itself. 
 I'm not really convinced that it's worth it, though.



If it isn't, that
would make `?=` (or '??=' though I don't see the need for double '?'s)


Because it's the in-place version of "??", obviously.


a
special statement, a special case that someone who's familiar with how
other in-place operators work, would be thrown for a loop.


Really?  Quick straw poll: how often do people care how in-place 
operators are implemented?



The other use
cases look like they break down in a different manner than they actually do:

person?.name

looks like it would break down similar to

person().name

but it doesn't because '?' by itself is not an operator.
similarly:

person?[0]

looks like it would break down similar to

person()[0]

but again, the operator is '?[...]' not '?'


Sorry, not buying this one.  As you said, "?" is not an operator, so 
"a?.b" clearly can't break down into "a? .b".  This all rather feels 
like you are trying to find justifications for not liking these 
operators rather just saying "I don't like them," and frankly I'd 
respect you more if you just said "I don't like them."


(For the record, I don't like most of them.  There are clear use cases 
for "??" and "??=", but the use cases I've seen for "?." and "?[]" 
aren't convincing to me.)



This also raises the question of other operators that could be made null
aware. Why not:

func?()

?-num

?~num

num ?+ other

Why not other reflective operators?

num ?+= other


Why not indeed.  I haven't seen any convincing use cases (and nor has 
the PEP, though I doubt Steve was looking for them), but they aren't 
inherently any more weird than "?." and "?[]".



I think this could be helped by simply making '?' an operator with a very
high order of operations, so that pretty-much any expression on the LHS is
guarded for 'NoneType' AttributeErrors:

val = person[0]?
val = person.name?


Um.  How is that supposed to parse?  "person[0]" has already been 
evaluated by the time the "?" operator gets anywhere near it.  Unless 
you are proposing some major surgery to the parser (which I'm pretty 
sure isn't going to happen), this has no chance of getting through. 
Good thing too, because it's a lot more surprising than the alternatives.



I also disagree with the idea that None is special enough to warrant such
special behavior. There are other special None-like objects (as David Mertz
pointed out) like NaN and custom place-holders for cases where None is a
valid argument.


NaN isn't used like None, though, and custom sentinels aren't that common.


Yet another possibility is to make '?' signify a parameter who's default
value is an expression that should be evaluated when necessary:

def func(data: List = []?):
 ...

That gets closer to another often requested feature: delayed expression
evaluation (as Steve D'Aprano pointed out).
So there are other, possibly better uses for the '?' symbol. It's something
that needs to be carefully considered.


While my immediate reaction is "yuk", your use of "?" does not conflict 
with any use in the PEP, so this is a red herring.


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-26 Thread Kyle Lahnakoski


On 2018-07-25 23:53, David Mertz wrote:
> On Wed, Jul 25, 2018, 11:27 PM Chris Angelico  > wrote:
>
>
> means that you cannot do this:
>
> >>> NullCoalesce(spam).nil is None
>
> This IS fundamentally unfixable in a library.
>
>
> Right now, you can still always call .unbox() at the end to get the
> underlying value. I agree that's a little ugly, hence why I added the
> wrapt proxy stuff. Most operations trigger unboxing, but indeed not
> simply echoing to the shell.
>

Chris is correct to point out this problem with comparing to None. I
have that problem with my own version of the proxy library, similar to
what David is building:  I use the proxy  heavily; to the point where
almost any line may be touching a proxy rather than a real value. To
avoid bugs, I disallow "is None" comparisons, mandating "== None" instead. 

Using unbox() is an alternative,  but it is uglier than than swapping
"as" for "==".


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-26 Thread Mikhail V
On Thu, Jul 26, 2018 at 5:10 AM, Steven D'Aprano  wrote:
> On Wed, Jul 25, 2018 at 05:11:08PM -0500, Abe Dillon wrote:
>> The problem here is not whether it's explicit. It's about Readability and
>> conciseness. Using symbols in place of words almost always harms
>> readability in favor of conciseness.
>
[...]

> Do you know what helps readability? *Learning to read*. Once you have
> learned to read ?. and friends, they will be as readable as . and
> slicing is now.

No it is not like that.
E.g. slicing is intuitive and straightforward concept even for a non-programmer.

And no, it is not (only) about learning.
For example, no matter how experienced a programmer is,
complex comprehensions will be less readable than the
same construct written in loops and ifs.

Or say this:

user?.profile?.food

will be less readable than say:

user » profile » food

No matter how long you learn it, the former remains ugly and
obfuscating.
With that said, I don't say this syntax deserves something better,
I just say that I can't see how your "learn more" argument applies
here.



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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-26 Thread Rhodri James

On 25/07/18 23:11, Abe Dillon wrote:

The problem here is not whether it's explicit. It's about Readability and
conciseness. Using symbols in place of words almost always harms
readability in favor of conciseness.

value = person.name if person.name else person


ITYM
  value = person.name if person.name is not None else None


almost reads like english (aside from being a weird and totally uncommon
use case)


I think Nicholas (?) was right to observe that it's uncommon to not want 
to know where a deeply nested attribute access failed.  Exactly what you 
want to do when an underlying library (presumably) has "helpfully" 
turned non-existent attributes into Nones is going to vary tremendously 
from application to application.


On the other hand,

  value = parameter ?? default

encapsulates a very common usage, and doesn't read badly compared with:

  value = parameter if parameter is not None else default

which is a tad wordy.  That example isn't too bad, but replace 
"parameter" with "spam.spam.spam.eggs" and DRY suddenly becomes a rather 
more important principle :-)


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-26 Thread Rhodri James

On 25/07/18 23:36, David Mertz wrote:

The fact that a while bunch have people have commented on this subthread
while not recognizing that the semantics of the '?.' and the if blocks are
entirely different suggests the operators are but magnets.


*Entirely* different?  Rubbish.  It's more like the difference between 
"+" and attempting to render "+" as a function using dunder methods.


I'm not keen on "?." and "?[]", but they are nothing like as bad as you 
are implying, and certainly not as bad as introducing a whole new 
concept like boxed types.


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-26 Thread Rhodri James

On 26/07/18 05:25, Raymond Hettinger wrote:

This PEP is one step further away from Python reading like executable 
pseudo-code.


+1000

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-26 Thread Nicholas Cole
The curious thing about PEP 505 as far as I can see is that it
introduces a new piece of syntax -- and for many people (to judge from
the reactions here) a controversial piece of syntax -- to solve what
seems to be a rather specific problem.  The use-case that seems most
discussed is unpacking information from nested JSON.

One of the things that makes me really twitch about the examples like

food = ham?.eggs?.spam?.chips

is that I don't usually deal with deeply nested structures like that
where it wouldn't matter to me which level of the nest returned a
value.

But let's leave that aside, because it seems to be an issue people
face. For the specific case mentioned, what would be wrong with a
utility function that looked something like:

# Warning - typed on gmail before I've had my morning coffee and so not
# at all tested, but I hope you can see what I mean.

def nested_conditional_find(search_this, *args):
 this = search_this
 for term in args:
  new_this = getattr(search_this, term)
  if new_this is None:
   return this
  else:
   this = new_this

then you could use this function as:

food = nested_conditional_find(ham, 'eggs', 'spam', 'chips')

One could even imagine adding extra tests along the way to a function
like that, raising attribute errors if the wrong kind of data was
encountered etc.

What problem does PEP 505 add that can't be solved very nearly as
elegantly by a utility function?  PEP 505 doesn't seem to be about
speed, only convenience.

For that matter, for specific use cases, why couldn't objects be
created where the attribute access functioned in just this kind of
way?  (not example code I'm willing to attempt before coffee ;-) )

Just a thought.

I've carefully avoided words like 'pythonic', 'unpythonic',
'explicit', 'implicit', 'compact', 'bug-magnet' or 'perl'.

Best wishes,

N

P.S. As an aside, in examples like food = spam?.eggs?.bacon -- if
bacon is None then food is None, even if there were in fact eggs and
spam.  That thought tells me it must be breakfast time.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-26 Thread Elazar
Just wanted to note another possibility (most likely to be added to the
"rejected solutions" section).

Add a prefix "!" operator, which will work similarly to the
iterator-unpacking operator "*", but for None.
The expression "[!x]" is equivalent to the expression "[] if x is None else
[x]".

This can be combined with the "or" operator, now working as expected since
it's about lists, and a simple "first" or "single" library function.

Example:

optdict = dict(encoding=single([!encoding] or
sys.getdefaultencoding()), css=options.css)

It is more verbose than the proposed "??" operator (which I personally
like), but maybe it's less line noise.
One can use it with simple parens and get a tuple, "(!x) or y". note that
"(!x or y)" is a syntax error in this case.


Another, related idea: instead of "??" use a double-token operator "! or":

value = ham! or spam! or eggs

optdict = dict(encoding=encoding! or sys.getdefaultencoding(),
css=options.css)

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-26 Thread Jonathan Fine
Hi All

To start this thread, on 18 July, Steve Dower wrote:
> Possibly this is exactly the wrong time to propose the next big syntax
> change, since we currently have nobody to declare on it, but since we're
> likely to argue for a while anyway it probably can't hurt (and maybe this
> will become the test PEP for whoever takes the reins?).

On 26 July, Raymond Hettinger wrote:
> It probably is the wrong time and probably can hurt (by introducing
> divisiveness when we most need for be focusing on coming together). [...]

+10

Here's some good news for Raymond. On 23 July, Steve Dower wrote:
---
> [...] I'm going to duck out of the discussions
> here now, since they are not as productive as I'd hoped, and once we have a
> BDFL-replacement I'll reawaken it and see what is required at that point.
---
and this is Steve's last post (so far) to the discussion.

+10

If you've not seen this message from Steve before, you're forgiven.
This topic has about 200 messages. Who's got time to read them all
them all?

If you want to have a go, they're listed by date at
https://mail.python.org/pipermail/python-ideas/2018-July/thread.html#52036

Regarding discussion of PEP 505, I'll follow the advice and example of
Raymond and Steve. Which is to pick it up again later, once we've got
proper cover for the BDFL's vacation. Have a nice holiday, Guido.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Amit Green
On Thu, Jul 26, 2018 at 1:09 AM, Steven D'Aprano 
wrote:

> On Thu, Jul 26, 2018 at 01:02:47AM -0400, Amit Green wrote:
>
> > 3.  The problem is way deeper than simply adding '?.' and other
> operators.
> > For real use cases, you also need to say "how far" the an operator can
> > "spread" -- and this is real hard to solve.
>
> Why do you think that is the case? No other operators "spread". Why
> should these?
>

If you take 'a?.b.c' then if the first '?.' yields none, logically you
don't want to evaluate the second '.'; otherwise you have to write:

a?.b?.c -- And this starts to look like line noise.

If you also implemented a concept such as use non-aware operators in
function calls: such as:

f(a, b?, c) -- which would mean collapse the whole thing out of
non-existance if 'b' yields none (i.e.: don't call function f) -- how far
does this spread?  Outside of f, if you then write:

f(a, b?, c).d.e

Does this also mean don't evaluate the '.d' & '.e' ?

And both of these examples are from *REAL* uses cases in my code I would
want to use none-aware operators.


>
> > 4.  Coming up with a readable syntax that doesn't look like line noise is
> > really hard; and very subjective.
>
> Define "line noise".
>
> Is a.b.c syntax line noise?
>
> Is a**b**c syntax line noise?
>
> Is a == b == c line noise?
>
>
>
These examples, from python, all look great & are very readable.  Which is
why python is such a great language :)

Simple non-aware operators are also very readable, such as: a?.b

This starts to become unreadable & line noise: a?.b.c.d ?? "hi".

Again, though it is subjective -- as is clearly evident by the discussions
in this group.

My simple point above is -- I really do want this feature -- but having
tried for days, I can't come up with a really clean syntax to capture all
of my *OWN* use cases ... let alone others...

Anyway, as I said, I think we have more important issues to address right
now, than this very difficult issue & I'll write up more tomorrow.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Steven D'Aprano
On Thu, Jul 26, 2018 at 01:02:47AM -0400, Amit Green wrote:

> 3.  The problem is way deeper than simply adding '?.' and other operators.
> For real use cases, you also need to say "how far" the an operator can
> "spread" -- and this is real hard to solve.

Why do you think that is the case? No other operators "spread". Why 
should these?


> 4.  Coming up with a readable syntax that doesn't look like line noise is
> really hard; and very subjective.

Define "line noise".

Is a.b.c syntax line noise?

Is a**b**c syntax line noise?

Is a == b == c line noise?



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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Steven D'Aprano
On Wed, Jul 25, 2018 at 11:09:35PM -0400, David Mertz wrote:

> Chris Angelica provided a more accurate translation.  Do you not see that
> the fact that your *second* try at understanding the actual behavior is
> still wrong suggest that this operator is a HUGE bug magnet?!

Oh what a load of FUD.

The whole point of having an operator do this means that we don't have 
to duplicate the semantics of the operator in plain Python.

Very few people get the semantics of x + y right. If (generic) you think 
that it is:

return x.__add__(y)

you're wrong. If you think it is:

try:
return x.__add__(y)
except AttributeError:
return y.__radd__(x)

you're still wrong. If you think it is something like this:

try:
adder = type(x).__add__
operands = (x, y)
except AttributeError:
try:
adder = type(y).__radd__
operands = (y, x)
except AttributeError:
raise TypeError from None
return adder(*operands)

you're still wrong. But *nobody cares* because outside of some 
incredibly rare and specialised uses, nobody needs to emulate the 
semantics of + in pure Python. They just call the + operator, or at 
worst call the operator.add function.

We have the syntax "yield from" because it is *really complicated* for 
one generator to delegate to another generator. Emulating the yield from 
call isn't necessary, because we have yield from.

(If you think that "yield from" is equivalent to "for x in subgenerator: 
yield x", you're wrong too.)

And likewise, if we have these new operators, that means that those who 
need them won't have to emulate them in pure Python. They can just use 
the operators.

The idea that using the operators will be "a bug magnet" because the 
implementation is (allegedly) complex is ludicrous.


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Amit Green
 On Thu, Jul 26, 2018 at 12:25 AM, Raymond Hettinger <
raymond.hettin...@gmail.com> wrote:

> It probably is the wrong time and probably can hurt (by introducing
> divisiveness when we most need for be focusing on coming together).
>
> This PEP also shares some traits with PEP 572 in that it solves a somewhat
> minor problem with   new syntax and grammar changes that affect the look
> and feel of the language in a way that at least some of us (me for example)
> find to be repulsive.
>
> This PEP is one step further away from Python reading like executable
> pseudo-code.  That trait is currently a major draw to the language and I
> don't think it should get tossed away just to mitigate a minor irritant.
>

+1.

Also this whole none-aware problem is really really complicated, so I'd
like to add a few thoughts:

1.  I spent a few days on it last year, and came to the following
conclusions:

2.  It is a *really* useful feature -- that I want in quite a lot of code
that I write.

3.  The problem is way deeper than simply adding '?.' and other operators.
For real use cases, you also need to say "how far" the an operator can
"spread" -- and this is real hard to solve.

4.  Coming up with a readable syntax that doesn't look like line noise is
really hard; and very subjective.

Based on all that, I have to agree -- now is not the time to try to resolve
these issues, there are more important issues to resolve -- I'll write more
on that tomorrow.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Nicholas Chammas
On Thu, Jul 26, 2018 at 12:17 AM David Mertz  wrote:

> On Thu, Jul 26, 2018 at 12:00 AM Nicholas Chammas <
> nicholas.cham...@gmail.com> wrote:
>
>> Forgive me for being slow. I'm missing what's different in semantics
>> between the translation above and Chris's translation below:
>>
>
> You are VERY close now.  You have more SPAM, so yours is better:
>



Understood. Thanks for clarifying. I think Chris was referring to this in
an earlier message (when I made my first attempt at translating) when he
said:

> Aside from questions of repeated evaluation/assignment, yes. The broad
> semantics should be the same.

So the meaning of my translation matches the "intention" of the original
PEP 505 expression, but I see the danger in offering up such loose
translations. Getting the meaning right but missing important details (like
repeated evaluation) does not inspire confidence.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Raymond Hettinger


> On Jul 18, 2018, at 10:43 AM, Steve Dower  wrote:
> 
> Possibly this is exactly the wrong time to propose the next big syntax 
> change, since we currently have nobody to declare on it, but since we're 
> likely to argue for a while anyway it probably can't hurt (and maybe this 
> will become the test PEP for whoever takes the reins?).

It probably is the wrong time and probably can hurt (by introducing 
divisiveness when we most need for be focusing on coming together).

This PEP also shares some traits with PEP 572 in that it solves a somewhat 
minor problem with   new syntax and grammar changes that affect the look and 
feel of the language in a way that at least some of us (me for example) find to 
be repulsive.

This PEP is one step further away from Python reading like executable 
pseudo-code.  That trait is currently a major draw to the language and I don't 
think it should get tossed away just to mitigate a minor irritant.

We should also consider a moratorium on language changes for while.  There is 
more going on than just a transition to a post-bdfl world.  The other 
implementations of Python are having a hard time keeping up with our recent, 
ferocious rate of change.  Even among the core developers, most people are not 
fully up to date learning all the new features that have already been added 
(how many of you are competent with typing, data classes, generalized 
unpacking, concurrent futures, async, the scoping rules for exceptions and 
comprehensions, the hundreds of niggling changes in the past few releases, 
__init_subclass__, __set_name__, details of import logic, issues with SSL 
certificates, new collections ABCs, etc.?)  We've been putting major changes in 
faster than anyone can keep up with them.  We really need to take a breath.


Raymond




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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread David Mertz
On Thu, Jul 26, 2018 at 12:00 AM Nicholas Chammas <
nicholas.cham...@gmail.com> wrote:

> Forgive me for being slow. I'm missing what's different in semantics
> between the translation above and Chris's translation below:
>

You are VERY close now.  You have more SPAM, so yours is better:

In [1]: class Spam:
   ...: @property
   ...: def eggs(self):
   ...: print("SPAM SPAM SPAM")
   ...: return "eggs"
   ...:
In [2]: spam = Spam()
In [3]: _tmp = spam
In [4]: if _tmp is not None:
   ...:  _tmp = _tmp.eggs
   ...:  if _tmp is not None:
   ...:  _tmp = _tmp.bacon
   ...: food = _tmp
   ...: del _tmp
   ...: food
   ...:
SPAM SPAM SPAM
-
AttributeError  Traceback (most recent call last)
 in ()
  2  _tmp = _tmp.eggs
  3  if _tmp is not None:
> 4  _tmp = _tmp.bacon
  5 food = _tmp
  6 del _tmp

AttributeError: 'str' object has no attribute 'bacon'
In [5]: if spam is not None and spam.eggs is not None:
   ...: food = spam.eggs.bacon
   ...:
SPAM SPAM SPAM
SPAM SPAM SPAM
-
AttributeError  Traceback (most recent call last)
 in ()
  1 if spam is not None and spam.eggs is not None:
> 2 food = spam.eggs.bacon
  3

AttributeError: 'str' object has no attribute 'bacon'



-- 
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.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread David Mertz
BTW, even for the "compare to None" issue, the situation in 0.1.1 isn't as
bad as you might think.  Definitely a ""
cannot be compared as "is None".  But even there, this works:

>>> NullCoalesce(spam).bacon

>>> NullCoalesce(spam).bacon == None
True
>>> NullCoalesce(spam).bacon == 0
False
>>> NullCoalesce(spam).bacon is None
False


So yeah, the docs should say "If you are using the `coalescing` library,
use `==` rather than `is` to compare values with None".

Yes, that's contrary to best style in general Python... but it's a pretty
small change to make in that specialized code that needs to deal with
"hierarchical semi-structured data that uses None (rather than missing
attributes or other sentinels) to mark unreachable branches."


On Wed, Jul 25, 2018 at 11:53 PM David Mertz  wrote:

> On Wed, Jul 25, 2018, 11:27 PM Chris Angelico  wrote:
>
>> > That's a bug in my proxy too.  I'll figure out how to fix it in 0.1.2
>> soon.
>> > This is early alpha, and the things you're noting are valuable bug
>> reports.
>> > But none of this is fundamentally unfixable in a library, nor even
>> > especially difficult.
>>
>> If you're going to make that work, then by definition you would be
>> wrapping up the None, right? Which would mean that every one of the
>> prints would say "". Which, in turn,
>> means that you cannot do this:
>>
>> >>> NullCoalesce(spam).nil is None
>>
>> or rather, it will always be False. With PEP 505, you most certainly
>> *can* do this check, because it would really truly be None.
>>
>> This IS fundamentally unfixable in a library.
>>
>
> If your meaning of "fix" is simply "add new syntax", of course that's
> true. If it's "solve the actual problem that motivates the PEP" I can
> definitely fix it.
>
> Right now, you can still always call .unbox() at the end to get the
> underlying value. I agree that's a little ugly, hence why I added the wrapt
> proxy stuff. Most operations trigger unboxing, but indeed not simply
> echoing to the shell.
>
> I think I'll add a property spelled '_' to make it less busy (but more
> cryptic, I know). E.g.
>
> NullCoalesce(spam).nil.nil.nil._ is None'
>
> I also added an unbox() function that will pass through non-proxy objects
> untouched. So it's safe to unbox anything if you are unsure what it is.
>
> Of course I'm not claiming any library is without a need to work with it's
> quirks and limits. But they are very few even in this 4-hours-of-work alpha.
>
>>

-- 
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.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Nicholas Chammas
On Wed, Jul 25, 2018 at 11:09 PM David Mertz  wrote:

> On Wed, Jul 25, 2018 at 10:50 PM Nicholas Chammas <
> nicholas.cham...@gmail.com> wrote:
>
>> Indeed. Thanks for the counter-example. I think the correct translation
>> is as follows:
>> food = spam?.eggs?.bacon
>> Becomes:
>> food = None
>> if spam is not None and spam.eggs is not None:
>> food = spam.eggs.bacon
>>
> Did I get it right now? :)
>>
>
> Nope, still not right, I'm afraid!
>
> Chris Angelica provided a more accurate translation.
>

Forgive me for being slow. I'm missing what's different in semantics
between the translation above and Chris's translation below:

_tmp = spam
> if _tmp is not None:
> _tmp = _tmp.eggs
> if _tmp is not None:
> _tmp = _tmp.bacon
> food = _tmp
>

What's a case where they would do something different?

* If spam is None, they work the same -> None
* If spam is not None, but spam.eggs exists and is None, they work the same
-> None
* If spam is not None, but spam.eggs doesn't exist, they work the same ->
AttributeError
* If spam is not None, and spam.eggs is not None, but spam.eggs.bacon is
None, they work the same -> None
* If spam is not None, and spam.eggs is not None, but spam.eggs.bacon
doesn't exist, they work the same -> AttributeError
* If spam is not None, and spam.eggs is not None, and spam.eggs.bacon is
not None, they work the same -> bacon
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread David Mertz
On Wed, Jul 25, 2018, 11:27 PM Chris Angelico  wrote:

> > That's a bug in my proxy too.  I'll figure out how to fix it in 0.1.2
> soon.
> > This is early alpha, and the things you're noting are valuable bug
> reports.
> > But none of this is fundamentally unfixable in a library, nor even
> > especially difficult.
>
> If you're going to make that work, then by definition you would be
> wrapping up the None, right? Which would mean that every one of the
> prints would say "". Which, in turn,
> means that you cannot do this:
>
> >>> NullCoalesce(spam).nil is None
>
> or rather, it will always be False. With PEP 505, you most certainly
> *can* do this check, because it would really truly be None.
>
> This IS fundamentally unfixable in a library.
>

If your meaning of "fix" is simply "add new syntax", of course that's true.
If it's "solve the actual problem that motivates the PEP" I can definitely
fix it.

Right now, you can still always call .unbox() at the end to get the
underlying value. I agree that's a little ugly, hence why I added the wrapt
proxy stuff. Most operations trigger unboxing, but indeed not simply
echoing to the shell.

I think I'll add a property spelled '_' to make it less busy (but more
cryptic, I know). E.g.

NullCoalesce(spam).nil.nil.nil._ is None'

I also added an unbox() function that will pass through non-proxy objects
untouched. So it's safe to unbox anything if you are unsure what it is.

Of course I'm not claiming any library is without a need to work with it's
quirks and limits. But they are very few even in this 4-hours-of-work alpha.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Chris Angelico
On Thu, Jul 26, 2018 at 1:19 PM, David Mertz  wrote:
> On Wed, Jul 25, 2018 at 11:08 PM Chris Angelico  wrote:
>>
>> > Yeah, yeah.  I know it's alpha software I wrote two nights ago, and
>> > slightly
>> > patched 5 minutes before that post.  You fixed those concerns; I'll
>> > happily
>> > take PRs on fixing them better.
>>
>> PRs? Nope. I don't think it's possible to do this with correct
>> semantics without language support.
>>
>> With PEP 505, I could write this:
>>
>> >>> print(spam?.nil?.nil?.nil?.nil)
>> None
>>
>> Can you do that with your proxy?
>
>
> Oh yeah.  You are right! Thank you.
>
> That's a bug in my proxy too.  I'll figure out how to fix it in 0.1.2 soon.
> This is early alpha, and the things you're noting are valuable bug reports.
> But none of this is fundamentally unfixable in a library, nor even
> especially difficult.

If you're going to make that work, then by definition you would be
wrapping up the None, right? Which would mean that every one of the
prints would say "". Which, in turn,
means that you cannot do this:

>>> NullCoalesce(spam).nil is None

or rather, it will always be False. With PEP 505, you most certainly
*can* do this check, because it would really truly be None.

This IS fundamentally unfixable in a library.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread David Mertz
On Wed, Jul 25, 2018 at 11:08 PM Chris Angelico  wrote:

> > Yeah, yeah.  I know it's alpha software I wrote two nights ago, and
> slightly
> > patched 5 minutes before that post.  You fixed those concerns; I'll
> happily
> > take PRs on fixing them better.
>
> PRs? Nope. I don't think it's possible to do this with correct
> semantics without language support.
>
> With PEP 505, I could write this:
>
> >>> print(spam?.nil?.nil?.nil?.nil)
> None
>
> Can you do that with your proxy?
>

Oh yeah.  You are right! Thank you.

That's a bug in my proxy too.  I'll figure out how to fix it in 0.1.2
soon.  This is early alpha, and the things you're noting are valuable bug
reports.  But none of this is fundamentally unfixable in a library, nor
even especially difficult.

I doubt I'll ever even use my own software.  It's just a proof-of-concept
that we can achieve the ACTUAL purpose of PEP 505 with no language
changes.  I don't very often have a need to solve the problem PEP 505
does... even though I very often work in the very domain it is intended to
address (semi-structured nested data).  Even if the PEP could be a little
bit more elegant for a very few circumstances, it's just not anywhere close
to deserving syntax... especially not syntax that even proponents tend to
misunderstand the semantics of.

-- 
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.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread David Mertz
On Wed, Jul 25, 2018 at 10:50 PM Nicholas Chammas <
nicholas.cham...@gmail.com> wrote:

> Indeed. Thanks for the counter-example. I think the correct translation is
> as follows:
> food = spam?.eggs?.bacon
> Becomes:
> food = None
> if spam is not None and spam.eggs is not None:
> food = spam.eggs.bacon
>
Did I get it right now? :)
>

Nope, still not right, I'm afraid!

Chris Angelica provided a more accurate translation.  Do you not see that
the fact that your *second* try at understanding the actual behavior is
still wrong suggest that this operator is a HUGE bug magnet?!


> So, shame on me. I think this particular mistake reflects more on me than
> on PEP 505, but I see how this kind of mistake reflects badly on the folks
> advocating for the PEP (or at least, playing devil's advocate).
>

I really, really don't.  I think you see an intuitive behavior that would
be nice and useful in a certain area.  That behavior just isn't what the
PEP proposes though... it's kinda-sorta close enough to be lured into
thinking it's a good idea.

Honestly, I think the behavior of GreedyAccess in my little library I wrote
over the last couple nights is FAR more often what programmers ACTUALLY
want than NullCoalesce is.  Even Steve Dower—in the PEP and in this
discussion—acknowledges the appeal and utility of the GreedyAccess
behavior.  It's in the "Rejected Ideas" section, which is fair enough.

But in a library like mine... or indeed, in a much better library that you
or someone else writes... it's perfectly easy to have both classes, and
choose which behavior is more useful for your case.  A new syntax feature
can't let user decide which behavior (or maybe some other behavior
altogether) is most useful for their specific case.  A library does that
easily[*].

[*] In version 0.1.1 of coalescing—changed from 0.1—I added the option to
use a sentinel other than None if you want.  I'm not sure how useful that
is, but that idea was in some old PEPs, and I think in the Rejected Ideas
of 505.  With a library, I have a parameter that need not be used to switch
that[**].  E.g.:

NullCoalesce(foo, sentinel=float('nan')).bar.baz.blam

[**] Yes, I even handle NaN's in a special way because they are non-equal
even to themselves.  You could use empty string, or 0, or my_null =
object(), or whatever.
-- 
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.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Chris Angelico
On Thu, Jul 26, 2018 at 12:56 PM, David Mertz  wrote:
> On Wed, Jul 25, 2018 at 10:41 PM Chris Angelico  wrote:
>>
>> A bit problematic. But after (a) figuring out that your module is
>> named "coalesce" even though I installed "coalescing" AND (b) going
>> and separately installing wrapt, and finally (c) doing the import that
>> you didn't mention, we still have this fundamental problem:
>
>
> Yeah, yeah.  I know it's alpha software I wrote two nights ago, and slightly
> patched 5 minutes before that post.  You fixed those concerns; I'll happily
> take PRs on fixing them better.

PRs? Nope. I don't think it's possible to do this with correct
semantics without language support.

>> >>> spam.nil = None
>> >>> print(NullCoalesce(spam).nil.nil)
>> None
>> >>> print(NullCoalesce(spam).nil.nil.nil)
>> Traceback (most recent call last):
>>   File "", line 1, in 
>> AttributeError: 'NoneType' object has no attribute 'nil'
>
>
> Why is this wrong? This is EXACTLY the same behavior as the `?.` operator
> would have in the last case.  Do you not recognize the behavior you are
> advocating in PEP 505?

With PEP 505, I could write this:

>>> spam = SimpleNamespace()
>>> spam.nil = None
>>> print(spam?.nil)
None
>>> print(spam?.nil?.nil)
None
>>> print(spam?.nil?.nil?.nil)
None
>>> print(spam?.nil?.nil?.nil?.nil)
None

Can you do that with your proxy?

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Chris Angelico
On Thu, Jul 26, 2018 at 12:45 PM, David Mertz  wrote:
> On Wed, Jul 25, 2018 at 10:29 PM Chris Angelico  wrote:
>> It is *actually impossible* to
>> perfectly represent short-circuiting semantics in Python!
>
>
> It's INCREDIBLY EASY to represent short-circuiting semantics in Python! What
> on earth are you talking about?  That's what the if/elif/else blocks do.

Except for the aforementioned "single lookup, single assignment"
semantics. You can't achieve that with an if/else block.

>> And before you go "well that proves my point, this suggestion is bad",
>> let's
>> apply the same test to a few other pieces of syntax. Rewrite the
>> following statements without using the syntactic feature named in the
>> comment:
>
>
> This is childishly simple:
>
>>
>> # 1) Decorators
>> @deco
>> def func():
>> ...
>
>
> def func():
>...
> func = deco(func)

Okay. Try this then:

def deco(f):
print(globals()[f.__name__])
return f
func = "funky"
@deco
def func(): pass

Childishly simple? Or does it have its own subtleties? You might think
this is trivial and pointless, but consider the case of a writable
property:

class X:
@property
def spam(self): return 42
@spam.setter
def spam(self, val): print("Setting spam to", val)

This version won't work:

class X:
def spam(self): return 42
spam = property(spam)
def spam(self, val): print("Setting spam to", val)
spam = spam.setter(spam)

See how easy it is to create an imperfect representation?

>> # 3) and the big one: generator expressions
>> # yes, I'm deliberately using x multiple ways here
>> def f(x): return x*x
>> x = range(10)
>> x = (f(x) for x in x if x % 2)
>
>
> I'm not going to bother with that.  I'd fire anyone who wrote it, after code
> review.  Minus the abuse of names, it's just:
>
> def gen(xs):
>
> for x in xs:
>
> if x % 2:
>
> yield f(x)
>
> x = gen(xs)

Modulo a TON of subtleties about exactly what gets evaluated when.
Again, you've made an imperfect equivalence. So if you're going to
complain about people making ?. equivalences that aren't perfect, make
sure you're just as pedantic about existing syntax. You scored one out
of three, and only by punting to the existing PEP.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread David Mertz
On Wed, Jul 25, 2018 at 10:41 PM Chris Angelico  wrote:

> A bit problematic. But after (a) figuring out that your module is
> named "coalesce" even though I installed "coalescing" AND (b) going
> and separately installing wrapt, and finally (c) doing the import that
> you didn't mention, we still have this fundamental problem:
>

Yeah, yeah.  I know it's alpha software I wrote two nights ago, and
slightly patched 5 minutes before that post.  You fixed those concerns;
I'll happily take PRs on fixing them better.


> >>> from coalesce import NullCoalesce
> >>> from types import SimpleNamespace
> >>> spam, spam.eggs, spam.eggs.bacon = SimpleNamespace(),
> SimpleNamespace(), 42
> >>> NullCoalesce(spam).eggs.bacon
> 
>
> That isn't 42. That's a thing that, forever afterwards, will be a
> proxy.


Yeah.  That's a thing it does.  It's less of an issue than you think since,
e.g.:

>>> from coalesce import NullCoalesce
>>> from types import SimpleNamespace
>>> spam, spam.eggs, spam.eggs.bacon = SimpleNamespace(),
SimpleNamespace(), 42
>>> NullCoalesce(spam).eggs.bacon + 1
43
>>> NullCoalesce(spam).eggs.bacon * 1
42


Most things you actually do with the proxy wind up getting the value back
once it is used.  However, this seems to be a bug that I inherit from
wrapt.ObjectProxy:

>>> NullCoalesce(spam).eggs.bacon + 0
ValueError: wrapper has not been initialized


If you do an operation that combines the proxy value with "Falsey" values,
it doesn't do the implicit unboxing.  Same with e.g. `proxyval + ""` for
strings, unfortunately.  I'm not sure how to fix that.

>>> spam.nil = None
> >>> print(NullCoalesce(spam).nil.nil)
> None
> >>> print(NullCoalesce(spam).nil.nil.nil)
> Traceback (most recent call last):
>   File "", line 1, in 
> AttributeError: 'NoneType' object has no attribute 'nil'
>

Why is this wrong? This is EXACTLY the same behavior as the `?.` operator
would have in the last case.  Do you not recognize the behavior you are
advocating in PEP 505?

I recognize that the proxy value not always "auto-unboxing" is a limitation
that I don't like.

-- 
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.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Nicholas Chammas
On Wed, Jul 25, 2018 at 10:12 PM David Mertz  wrote:

> On Wed, Jul 25, 2018 at 9:47 PM Nicholas Chammas <
> nicholas.cham...@gmail.com> wrote:
>
>> > That is disingenuous, I think.  Can this raise an AttributeError?
>>> > spam?.eggs?.bacon
>>> > Of course it can! And this is exactly the pattern used in many
>>> examples in
>>> > the PEP and the discussion. So the PEP would create a situation where
>>> code
>>> > will raise AttributeError in a slightly—and subtly—different set of
>>> > circumstances than plain attribute access will.
>>>
>>
>
>> food = spam?.eggs?.bacon
>> Can be rewritten as:
>> food = spam
>> if spam is not None and spam.eggs is not None:
>> food = spam.eggs.bacon
>> They both behave identically, no? Maybe I missed the point David was
>> trying to make.
>>
>
> No, you illustrate it perfectly! I had to stare at your translation for a
> while to decide if it was really identical to the proposed
> `spam?.eggs?.bacon`.  The fact I have to think so hard makes the syntax
> feel non-obvious.
>
> Plus, there's the fact that your best effort at translating the proposed
> syntax is WRONG.  Even a strong proponent cannot explain the behavior on a
> first try.  And indeed, it behaves subtly different from plain attribute
> access in where it raises AttributeError.
>
> >>> spam = SimpleNamespace()
> >>> spam.eggs = None
> >>> spam.eggs.bacon
> AttributeError: 'NoneType' object has no attribute 'bacon'
>
> >>> # spam?.eggs?.bacon
> >>> # Should be: None
>
> >>> "Translation" does something different
> >>> food = spam
> >>> if spam is not None and spam.eggs is not None:
> ... food = spam.eggs.bacon
> >>> food
> namespace(eggs=None)
>

Indeed. Thanks for the counter-example. I think the correct translation is
as follows:

food = spam?.eggs?.bacon

Becomes:

food = None
if spam is not None and spam.eggs is not None:
food = spam.eggs.bacon

Did I get it right now? :)

What misled me was this example from the PEP

showing
how atoms are evaluated. The breakdown begins with `_v = a`, so I copied
that pattern incorrectly when trying to explain how an example assignment
would work, instead of translating directly from what I understood the PEP
505 variant should do.

So, shame on me. I think this particular mistake reflects more on me than
on PEP 505, but I see how this kind of mistake reflects badly on the folks
advocating for the PEP (or at least, playing devil's advocate).
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread David Mertz
On Wed, Jul 25, 2018 at 10:29 PM Chris Angelico  wrote:

> food = spam?.eggs?.bacon
>
> can be rewritten as
>
> _tmp = spam
> if _tmp is not None:
> _tmp = _tmp.eggs
> if _tmp is not None:
> _tmp = _tmp.bacon
> food = _tmp
>

Yes, that looks right.  Well, you need a `del _tmp` at the end; but it's
almost right.  My point was that both you and Nicholas Chammas failed to
recognize that the other translation was wrong... I recognize it does
something "kinda similar."  But the semantics of the operators are just
plain hard to grok, even by their strongest advocates.

I can write lots of things that are "mostly correct" already in Python.
Most easily, I can write:

try:
   food = spam.eggs.bacon
except:
  food = None


That does what is actually needed about 95% of the time.  It's also clear
and easy to understand.

It is *actually impossible* to
> perfectly represent short-circuiting semantics in Python!


It's INCREDIBLY EASY to represent short-circuiting semantics in Python!
What on earth are you talking about?  That's what the if/elif/else blocks
do.

And before you go "well that proves my point, this suggestion is bad", let's
> apply the same test to a few other pieces of syntax. Rewrite the
> following statements without using the syntactic feature named in the
> comment:
>

This is childishly simple:


> # 1) Decorators
> @deco
> def func():
> ...
>

def func():
   ...
func = deco(func)


OK, this one is harder.  The "mostly correct" version is easy.  But the
actual full version is nuanced (see
https://www.python.org/dev/peps/pep-0380/ for details).

# 2) "yield from"
> def chain(*iters):
> for iter in iters:
> yield from iter
>

# The simple approximation:
for iter in iters:

for _ in iter:

yield iter



> # 3) and the big one: generator expressions
> # yes, I'm deliberately using x multiple ways here
> def f(x): return x*x
> x = range(10)
> x = (f(x) for x in x if x % 2)
>

I'm not going to bother with that.  I'd fire anyone who wrote it, after
code review.  Minus the abuse of names, it's just:

def gen(xs):

for x in xs:

if x % 2:

yield f(x)

x = gen(xs)



-- 
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.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Chris Angelico
On Thu, Jul 26, 2018 at 12:30 PM, David Mertz  wrote:
> Btw. Here's a way of spelling the proposed syntax that gets the semantics
> right:
>
 # pip install coalescing
 NullCoalesce(spam).eggs.bacon

Let's try it.

rosuav@sikorsky:~$ sudo python3 -m pip install coalescing
Collecting coalescing
  Downloading 
https://files.pythonhosted.org/packages/f3/f4/120f04cc59f9fa8c55c711b67f1c9c34d8a59c34cd69249e6ff61b098987/coalescing-0.1.1.tar.gz
Installing collected packages: coalescing
  Running setup.py install for coalescing ... done
Successfully installed coalescing-0.1.1

rosuav@sikorsky:~$ python3
Python 3.8.0a0 (heads/literal_eval-exception:ddcb2eb331, Feb 21 2018, 04:32:23)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from coalescing import NullCoalesce
Traceback (most recent call last):
  File "", line 1, in 
ModuleNotFoundError: No module named 'coalescing'
>>> from coalesce import NullCoalesce
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/local/lib/python3.8/site-packages/coalesce.py", line 56,
in 
import wrapt
ModuleNotFoundError: No module named 'wrapt'

A bit problematic. But after (a) figuring out that your module is
named "coalesce" even though I installed "coalescing" AND (b) going
and separately installing wrapt, and finally (c) doing the import that
you didn't mention, we still have this fundamental problem:

rosuav@sikorsky:~$ python3
Python 3.8.0a0 (heads/literal_eval-exception:ddcb2eb331, Feb 21 2018, 04:32:23)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from coalesce import NullCoalesce
>>> from types import SimpleNamespace
>>> spam, spam.eggs, spam.eggs.bacon = SimpleNamespace(), SimpleNamespace(), 42
>>> NullCoalesce(spam).eggs.bacon


That isn't 42. That's a thing that, forever afterwards, will be a
proxy. And look at this:

>>> spam.nil = None
>>> print(NullCoalesce(spam).nil)

>>> print(NullCoalesce(spam).nil.nil)
None
>>> print(NullCoalesce(spam).nil.nil.nil)
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'NoneType' object has no attribute 'nil'
>>>

Whoops.

So, no, this is most definitely NOT equivalent to the proposed semantics.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread David Mertz
So now at least TWO proponents of 505 cannot successfully translate a very
simple example taken almost directly from the PEP!

Is that REALLY a good argument for it being helpful, and not being a bug
magnet?!

On Wed, Jul 25, 2018 at 9:57 PM Chris Angelico  wrote:

> On Thu, Jul 26, 2018 at 11:45 AM, Nicholas Chammas
>  wrote:
> > On Wed, Jul 25, 2018 at 9:20 PM Chris Angelico  wrote:
> >>
> >> On Thu, Jul 26, 2018 at 11:02 AM, David Mertz  wrote:
> >> > That is disingenuous, I think.  Can this raise an AttributeError?
> >> >
> >> > spam?.eggs?.bacon
> >> >
> >> > Of course it can! And this is exactly the pattern used in many
> examples
> >> > in
> >> > the PEP and the discussion. So the PEP would create a situation where
> >> > code
> >> > will raise AttributeError in a slightly—and subtly—different set of
> >> > circumstances than plain attribute access will.
> >>
> >> I don't understand. If it were to raise AttributeError, it would be
> >> because spam (or spam.eggs) isn't None, but doesn't have an attribute
> >> eggs (or bacon). Exactly the same as regular attribute access. How is
> >> it slightly different? Have I missed something?
> >
> >
> > That was my reaction, too.
> >
> > food = spam?.eggs?.bacon
> >
> > Can be rewritten as:
> >
> > food = spam
> > if spam is not None and spam.eggs is not None:
> > food = spam.eggs.bacon
> >
> > They both behave identically, no? Maybe I missed the point David was
> trying
> > to make.
>
> Aside from questions of repeated evaluation/assignment, yes. The broad
> semantics should be the same.
>
> (If you want to get technical, "spam" gets evaluated exactly once,
> "spam.eggs" a maximum of once, and "food" gets assigned exactly once.
> Your equivalent may evaluate and assign multiple times.)
>
> ChrisA
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
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.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread David Mertz
On Wed, Jul 25, 2018 at 9:47 PM Nicholas Chammas 
wrote:

> > That is disingenuous, I think.  Can this raise an AttributeError?
>> > spam?.eggs?.bacon
>> > Of course it can! And this is exactly the pattern used in many examples
>> in
>> > the PEP and the discussion. So the PEP would create a situation where
>> code
>> > will raise AttributeError in a slightly—and subtly—different set of
>> > circumstances than plain attribute access will.
>>
>

> food = spam?.eggs?.bacon
> Can be rewritten as:
> food = spam
> if spam is not None and spam.eggs is not None:
> food = spam.eggs.bacon
> They both behave identically, no? Maybe I missed the point David was
> trying to make.
>

No, you illustrate it perfectly! I had to stare at your translation for a
while to decide if it was really identical to the proposed
`spam?.eggs?.bacon`.  The fact I have to think so hard makes the syntax
feel non-obvious.

Plus, there's the fact that your best effort at translating the proposed
syntax is WRONG.  Even a strong proponent cannot explain the behavior on a
first try.  And indeed, it behaves subtly different from plain attribute
access in where it raises AttributeError.

>>> spam = SimpleNamespace()
>>> spam.eggs = None
>>> spam.eggs.bacon
AttributeError: 'NoneType' object has no attribute 'bacon'

>>> # spam?.eggs?.bacon
>>> # Should be: None

>>> "Translation" does something different
>>> food = spam
>>> if spam is not None and spam.eggs is not None:
... food = spam.eggs.bacon
>>> food
namespace(eggs=None)


-- 
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.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Nicholas Chammas
On Wed, Jul 25, 2018 at 9:20 PM Chris Angelico  wrote:

> On Thu, Jul 26, 2018 at 11:02 AM, David Mertz  wrote:
> > That is disingenuous, I think.  Can this raise an AttributeError?
> >
> > spam?.eggs?.bacon
> >
> > Of course it can! And this is exactly the pattern used in many examples
> in
> > the PEP and the discussion. So the PEP would create a situation where
> code
> > will raise AttributeError in a slightly—and subtly—different set of
> > circumstances than plain attribute access will.
>
> I don't understand. If it were to raise AttributeError, it would be
> because spam (or spam.eggs) isn't None, but doesn't have an attribute
> eggs (or bacon). Exactly the same as regular attribute access. How is
> it slightly different? Have I missed something?
>

That was my reaction, too.

food = spam?.eggs?.bacon

Can be rewritten as:

food = spam
if spam is not None and spam.eggs is not None:
food = spam.eggs.bacon

They both behave identically, no? Maybe I missed the point David was trying
to make.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread James Lu
What if we used ? after the statement beginning?

name ?= person.name
custom_query ?= entity.get_query(context)
# Becomes None if entity is None. Raise an exception if entity is not None and 
get_query is None or undefined.
custom_query ??= entity.get_query(context)
# If entity, entity.get_query, entity.get_query(context) evaluate to null, the 
operation short-circuits and custom_query becomes None
await? foo
with? bar as baz:
# this only runs if bar is not None
pass


?= only short circuits into None when the first evaluation is None (the weak 
operator)
??= short circuits into None whenever any evaluation is None or raises an 
AttributeError. (the strong operator)

I’m imagining the strong operator would be useful especially for duck typing. 
No more hasattr checks, no more isinstance checks. 

I would like to see some real world use cases for none aware operators that 
couldn’t be covered by these none aware assignment operators.

Previous code:
# original code
a ?= b.c
# another, second, programmer comes along and changes it to
a ?= b.c.d

The interpreter would raise an exception, if “d” was None or not defined on 
“c”. If this is intended behavior, this forces the second programmer to 
explicitly mark that all attribute access is coalescing with the strong 
operator, instead of the interpreter swallowing the exception now and emitting 
an exception later. The previous code assumes “b” is None, which in reality may 
represent the state of a network socket or a file transfer. The program may 
display that the operation was complete, leading to a bug in the output. 

I believe this is more readable as well.
> On Jul 25, 2018, at 7:32 PM, python-ideas-requ...@python.org wrote:
> 
> PEP 505: None-aware operators
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Steven D'Aprano
On Tue, Jul 24, 2018 at 08:07:36AM -0400, Richard Damon wrote:

> The fact that you changed NullCoalesce into Foo to show lack of 
> explicitness seems a straw-man.

I understood Rhodri as making the point that if you don't know what 
NullCoalesce means or does, it might as well be called Foo. There's no 
hint in the syntax that something magical is happening:


MyClass(obj).spam.eggs  # ordinary attribute lookup

YourClass(obj).spam.eggs  # still ordinary attribute lookup

Mxyzptlk(obj).spam.eggs  # looks like ordinary attribute lookup

NullCoalesce(obj).spam.eggs  # IT'S A TRAP!



> Words are FULL of meaning, while symbols are less so.

It isn't a competition to squeeze as much meaning as possible into a 
single word or symbol. Precision is more important than fullness.

A case in point: the word "add" has six meanings listed by WordNet, and 
the Mobi Thesaurus gives 102 synonyms for it. A function or method called "add" 
could do anything:

- add users to a database;
- add pages to a chapter;
- add elements to a set;
- add items to a queue;

etc. In contrast, the + symbol in Python has two standard meanings:

- numeric addition;
- sequence concatenation;

and while it is true that with operator overloading a class could make 
the + operator do anything, that is usually taken as an argument to 
avoid operator overloading, or at least use it cautiously.

Surely you don't think that the + operator is a mistake because the word 
"add" is more full of meaning than the symbol? If not, what point were 
you trying to make?


> The biggest issue I see with the use of ? here is 
> that ? does have some meaning, it says we are going to be (or have) 
> asked a question, it doesn’t tell us what the question is.

Sometimes you just have to learn the meanings of words or symbols.

What does NullCoalesce mean? Until this PEP was proposed, I had no idea 
this was even a thing, and in truth I actually had to look up "coalesce" 
in a dictionary to be sure I understood it correctly, because the 
context doesn't seem quite right.

(It still doesn't -- it might be the standard comp sci term for this 
feature, but I don't think it quite matches the ordinary usage of the 
word.)

Ask a dozen programming beginners what "NullCoalesce" does, and I expect 
every one of them will say "No idea".

Strangely enough, nobody complains about having to learn what "import" 
does, or slicing syntax x[:], or string backslash escapes "\n", or 
"property". Because we're used to them, we just accept that you have to 
learn the meaning of things the first time you see them. We aren't born 
knowing what "class" does, or the difference between x[a] and x(a).

Every single one of us, without exception, had to learn what . means at 
some point or another.

And yet, its wailing and gnashing of teeth and panic in the streets over 
the idea that people might have to learn what ?. means in the same way 
they learned what **kwargs or mylist[1:] or obj.attr means.

"It's a question, but what is the question? How will I ever
find out? If only there was a website where I might look up
Python operators and learn what they do!!!"


> ?. has some indication that we are doing an attribute access that is 
> in some way conditional, but a?.b could mean that we are conditional 
> on a not being null, or it could be asking to suppress any and all 
> error in getting b, even if a is an int and thus doesn’t have a b. The 
> words carry a lot more meaning.

Yeah, because words are always obvious.

import ast  # Who can remember all these damned TLAs?
import bdm  # Births Deaths Marriages?
import csv  # Court Services Victoria?
import mailcap  # what the postman wears on his head?
import pickle  # something to do with condiments?
import turtle  # somebody is taking the micky
import curses  # good thing I'm not superstitious


"But Steve, you don't understand. Having to learn the meaning
 of words you haven't learned before is right and proper and
 unavoidable. But all new punctuation symbols must be intuitively
 obvious to newborn babies, or else they are the Devil's Mark,
 or Perl, not sure which is worse."

(Its called sarcasm, not "strawman". Just sayin'.)


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Steven D'Aprano
On Wed, Jul 25, 2018 at 12:12:40PM -0400, Nicholas Chammas wrote:

> When something is "explicit", as I understand it, that means it does what
> it says on the cover. There is no unstated behavior. The plain meaning of
> `v = a?.b` is that it expands to the longer form (`v = a; if a.b ...`), and
> it is just as explicit.

Right. We don't insist on writing


mydict.look_up_key_in_self_and_raise_keyerror_if_the_key_is_not_found(key="spam")

instead of 

mydict["spam"]

out of a mistaken idea that explicitness requires verbosity and that 
punctuation is always implicit.

Symbols (whether made of text or punctuation) have meaning, and that 
meaning has to be taken into account. You *can't* spell everything out 
in full. We always have to take the meaning of something as given, and 
that can be punctuation just as easily as words.


> This reminds me of something I read about once called Stroustrup's Rule
>  [1]:
> 
> > For new features, people insist on LOUD explicit syntax.
> > For established features, people want terse notation.
> 
> I think the "explicit vs. implicit" part of this discussion is probably
> better expressed as a discussion about "loud vs. terse" syntax. None of the
> operators in PEP 505 have implicit behavior, to the best of my
> understanding. It's just that the operators are new and have terse
> spellings.

That is a great observation! Thanks.


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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Greg Ewing

David Mertz wrote:
Sorry. From my tablet. "Bug magnets" (it really, really wants to 
autocorrect that)


At least it didn't correct it to "butt magnets". :-)

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Abe Dillon
*sorry, cat hit "send"...

Just reading those examples made me want to cry and go hide in a dark dark
cave and never come out. I'm sure using actual variable names would help a
bit, but not much.

As for the non-english nature of:
value = person.name

I highly disagree with the argument that since that is a step removed from
natural language readability that:
value = person?.name

Should be considered fair game. Nor do I buy the "other languages do it"
argument. Some of the syntax of Python is based on familiar patterns in
other languages (like '.' access) some of it is based on common math (e.g.
"=", "+", etc.) which is also taught in grade school. Some of the patterns
borrowed from other languages were a mistake and considered cruft. Some of
that cruft was scraped off in the 2to3 migration. Maybe "." should have
been apostrophe "s" all along. Maybe lambda should have been
'make_function'. That's not what we're here to discuss. A lot of languages
have a ternary operator (x ? y : z). Python wisely used words instead of
symbols and now many students don't even have to crack a book to decipher
Python's ternary operator. Adding crap to a language is easy. Removing it
is damn near impossible. You have to have extremely good reasons to add new
syntax and I don't have to defend any of Python's warts to justify
rejecting yours.

On Wed, Jul 25, 2018 at 6:15 PM, Abe Dillon  wrote:

> The two statements you wrote are not the same. The first statement will
>> error out if person is None.
>
> That's my bad. I was copying off of an erroneous example. Thanks for
> correcting me.
>
> The proposed None-aware operators are specifically designed to handle
>> variables that may be None.
>>
> Yes, I think the syntax that you've landed on is confusing enough that it
> opens the door to more errors than it closes. Just reading "(a?.b ?? c).d?.e"
> and "await a?.b(c).d?[e]"
>
>
> On Wed, Jul 25, 2018 at 6:06 PM, Nicholas Chammas <
> nicholas.cham...@gmail.com> wrote:
>
>> On Wed, Jul 25, 2018 at 6:11 PM Abe Dillon  wrote:
>>
>>> The problem here is not whether it's explicit. It's about Readability
>>> and conciseness. Using symbols in place of words almost always harms
>>> readability in favor of conciseness.
>>>
>>> value = person.name if person.name else person
>>>
>>> almost reads like english (aside from being a weird and totally uncommon
>>> use case)
>>>
>>> value = person?.name
>>>
>>> Is a huge step towards the concise illegible soup of symbols that Perl
>>> is famous for. It's a huge No from me.
>>>
>>
>> The two statements you wrote are not the same. The first statement will
>> error out if person is None. The proposed None-aware operators are
>> specifically designed to handle variables that may be None.
>>
>> The first statement should instead read:
>>
>> value = person.name if person is not None else person
>>
>> That's what `value = person?.name` means.
>>
>> As others have pointed out, I suppose the fact that multiple people have
>> messed up the meaning of the proposed operators is concerning. Perhaps the
>> PEP could be improved by adding some dead simple examples of each operator
>> and an equivalent statement that doesn't use the operator, to better
>> illustrate their meaning. But I gather that will do little in the way of
>> addressing some of the stronger objections raised here.
>>
>
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Abe Dillon
>
> The two statements you wrote are not the same. The first statement will
> error out if person is None.

That's my bad. I was copying off of an erroneous example. Thanks for
correcting me.

The proposed None-aware operators are specifically designed to handle
> variables that may be None.
>
Yes, I think the syntax that you've landed on is confusing enough that it
opens the door to more errors than it closes. Just reading "(a?.b ?? c).d?.e"
and "await a?.b(c).d?[e]"


On Wed, Jul 25, 2018 at 6:06 PM, Nicholas Chammas <
nicholas.cham...@gmail.com> wrote:

> On Wed, Jul 25, 2018 at 6:11 PM Abe Dillon  wrote:
>
>> The problem here is not whether it's explicit. It's about Readability and
>> conciseness. Using symbols in place of words almost always harms
>> readability in favor of conciseness.
>>
>> value = person.name if person.name else person
>>
>> almost reads like english (aside from being a weird and totally uncommon
>> use case)
>>
>> value = person?.name
>>
>> Is a huge step towards the concise illegible soup of symbols that Perl is
>> famous for. It's a huge No from me.
>>
>
> The two statements you wrote are not the same. The first statement will
> error out if person is None. The proposed None-aware operators are
> specifically designed to handle variables that may be None.
>
> The first statement should instead read:
>
> value = person.name if person is not None else person
>
> That's what `value = person?.name` means.
>
> As others have pointed out, I suppose the fact that multiple people have
> messed up the meaning of the proposed operators is concerning. Perhaps the
> PEP could be improved by adding some dead simple examples of each operator
> and an equivalent statement that doesn't use the operator, to better
> illustrate their meaning. But I gather that will do little in the way of
> addressing some of the stronger objections raised here.
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Nicholas Chammas
On Wed, Jul 25, 2018 at 6:11 PM Abe Dillon  wrote:

> The problem here is not whether it's explicit. It's about Readability and
> conciseness. Using symbols in place of words almost always harms
> readability in favor of conciseness.
>
> value = person.name if person.name else person
>
> almost reads like english (aside from being a weird and totally uncommon
> use case)
>
> value = person?.name
>
> Is a huge step towards the concise illegible soup of symbols that Perl is
> famous for. It's a huge No from me.
>

The two statements you wrote are not the same. The first statement will
error out if person is None. The proposed None-aware operators are
specifically designed to handle variables that may be None.

The first statement should instead read:

value = person.name if person is not None else person

That's what `value = person?.name` means.

As others have pointed out, I suppose the fact that multiple people have
messed up the meaning of the proposed operators is concerning. Perhaps the
PEP could be improved by adding some dead simple examples of each operator
and an equivalent statement that doesn't use the operator, to better
illustrate their meaning. But I gather that will do little in the way of
addressing some of the stronger objections raised here.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread David Mertz
Sorry. From my tablet. "Bug magnets" (it really, really wants to
autocorrect that)

And yes, the problem is that the equivalent is actually:

v = a
if v is not None: v=a.b

The semantics are simply not the ones that are intuitive to most people
reading 'v = a?.b'

On Wed, Jul 25, 2018, 7:01 PM Abe Dillon  wrote:

> The fact that a while bunch have people have commented on this subthread
>> while not recognizing that the semantics of the '?.' and the if blocks are
>> entirely different suggests the operators are but magnets.
>>
>
> Can you explain? What do you mean by "the operators are but magnets"?
>
> The "None coalescing" operator seems so similar to the short circuit
> behavior of "or" that it has pretty much no merit. It's compared to ternary
> statements in the last section of the PEP (which is suspiciously lacking
> the "or" pattern).
>
> I would agree that Python could use some more support for EAFP
>  style coding. An express-ionized
> version of try/catch might help there, but I'm pretty sure the search for
> an elegant solution to that has been relatively fruitless. The attribute
> access and indexing are just unreadable in my view. Maybe if the question
> mark came at the end of the expression it would be more readable and just
> mean, "if the preceding expression raises an attribute exception on a
> none-type object, ignore it and evaluate to None otherwise return the
> result of the evaluation" Then just use parentheses to capture the scope:
>
> initial = (person.name[0])? # handles if person is None or person.name is
> None
>
> but that still seems like a good way to end up with very ugly code.
> Haskel's Maybe seems like a much better and more readable approach.
>
>
>
> On Wed, Jul 25, 2018 at 5:36 PM, David Mertz  wrote:
>
>> The fact that a while bunch have people have commented on this subthread
>> while not recognizing that the semantics of the '?.' and the if blocks are
>> entirely different suggests the operators are but magnets.
>>
>> On Wed, Jul 25, 2018, 5:17 PM Nicholas Chammas <
>> nicholas.cham...@gmail.com> wrote:
>>
>>> On Mon, Jul 23, 2018 at 6:05 PM Giampaolo Rodola' 
>>> wrote:
>>>
 This:

 v = a?.b

 ...*implicitly* checks if value is not None [and continues execution].
 This:

 v = a
 if a.b is not None:
 v = a.b

 ...*explicitly* checks if value is not None and continues execution.

>>>
>>> I think both of those are equally explicit. It's just that one notation
>>> is more concise than the other. Explicitness and conciseness are related
>>> but different things.
>>>
>>> When something is "explicit", as I understand it, that means it does
>>> what it says on the cover. There is no unstated behavior. The plain meaning
>>> of `v = a?.b` is that it expands to the longer form (`v = a; if a.b ...`),
>>> and it is just as explicit.
>>>
>>> This reminds me of something I read about once called Stroustrup's Rule
>>> 
>>>  [1]:
>>>
>>> > For new features, people insist on LOUD explicit syntax.
>>> > For established features, people want terse notation.
>>>
>>> I think the "explicit vs. implicit" part of this discussion is probably
>>> better expressed as a discussion about "loud vs. terse" syntax. None of the
>>> operators in PEP 505 have implicit behavior, to the best of my
>>> understanding. It's just that the operators are new and have terse
>>> spellings.
>>>
>>> As a point of comparison, I think a good example of implicit behavior is
>>> type coercion. When you ask Python to add an int to a float
>>>
>>> a = 3 + 4.5
>>>
>>> all that you've explicitly asked for is the addition. However, Python
>>> implicitly converts the 3 from an int to a float as part of the operation.
>>> The type conversion isn't anywhere "on the cover" of the + operator. It's
>>> implicit behavior.
>>>
>>> [1] Bjarne Stroustrup makes the observation in this talk
>>>  at
>>> 23:00.
>>> ___
>>> Python-ideas mailing list
>>> Python-ideas@python.org
>>> https://mail.python.org/mailman/listinfo/python-ideas
>>> Code of Conduct: http://python.org/psf/codeofconduct/
>>>
>>
>> ___
>> Python-ideas mailing list
>> Python-ideas@python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>>
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Elazar
On Wed, Jul 25, 2018 at 3:11 PM Abe Dillon  wrote:

> The problem here is not whether it's explicit. It's about Readability and
> conciseness. Using symbols in place of words almost always harms
> readability in favor of conciseness.
>
> value = person.name if person.name else person
>
> almost reads like english (aside from being a weird and totally uncommon
> use case)
>
> value = person?.name
>
> Is a huge step towards the concise illegible soup of symbols that Perl is
> famous for. It's a huge No from me.
>
>
> Similarly,

Value is name of person

almost reads like english.

value = person.name

Starts to look like pearl (but does not avoid repetition; only hurts
english-like-readability) - or perhaps some other programming languages
that use similar operators, such as C#, Swift, Dart, F#, Kotlin and others.
As far as I know it is not generally considered a bad addition in any of
these languages, all of which put emphasis on readability.

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


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Abe Dillon
>
> The fact that a while bunch have people have commented on this subthread
> while not recognizing that the semantics of the '?.' and the if blocks are
> entirely different suggests the operators are but magnets.
>

Can you explain? What do you mean by "the operators are but magnets"?

The "None coalescing" operator seems so similar to the short circuit
behavior of "or" that it has pretty much no merit. It's compared to ternary
statements in the last section of the PEP (which is suspiciously lacking
the "or" pattern).

I would agree that Python could use some more support for EAFP
 style coding. An express-ionized
version of try/catch might help there, but I'm pretty sure the search for
an elegant solution to that has been relatively fruitless. The attribute
access and indexing are just unreadable in my view. Maybe if the question
mark came at the end of the expression it would be more readable and just
mean, "if the preceding expression raises an attribute exception on a
none-type object, ignore it and evaluate to None otherwise return the
result of the evaluation" Then just use parentheses to capture the scope:

initial = (person.name[0])? # handles if person is None or person.name is
None

but that still seems like a good way to end up with very ugly code.
Haskel's Maybe seems like a much better and more readable approach.



On Wed, Jul 25, 2018 at 5:36 PM, David Mertz  wrote:

> The fact that a while bunch have people have commented on this subthread
> while not recognizing that the semantics of the '?.' and the if blocks are
> entirely different suggests the operators are but magnets.
>
> On Wed, Jul 25, 2018, 5:17 PM Nicholas Chammas 
> wrote:
>
>> On Mon, Jul 23, 2018 at 6:05 PM Giampaolo Rodola' 
>> wrote:
>>
>>> This:
>>>
>>> v = a?.b
>>>
>>> ...*implicitly* checks if value is not None [and continues execution].
>>> This:
>>>
>>> v = a
>>> if a.b is not None:
>>> v = a.b
>>>
>>> ...*explicitly* checks if value is not None and continues execution.
>>>
>>
>> I think both of those are equally explicit. It's just that one notation
>> is more concise than the other. Explicitness and conciseness are related
>> but different things.
>>
>> When something is "explicit", as I understand it, that means it does what
>> it says on the cover. There is no unstated behavior. The plain meaning of
>> `v = a?.b` is that it expands to the longer form (`v = a; if a.b ...`), and
>> it is just as explicit.
>>
>> This reminds me of something I read about once called Stroustrup's Rule
>> 
>>  [1]:
>>
>> > For new features, people insist on LOUD explicit syntax.
>> > For established features, people want terse notation.
>>
>> I think the "explicit vs. implicit" part of this discussion is probably
>> better expressed as a discussion about "loud vs. terse" syntax. None of the
>> operators in PEP 505 have implicit behavior, to the best of my
>> understanding. It's just that the operators are new and have terse
>> spellings.
>>
>> As a point of comparison, I think a good example of implicit behavior is
>> type coercion. When you ask Python to add an int to a float
>>
>> a = 3 + 4.5
>>
>> all that you've explicitly asked for is the addition. However, Python
>> implicitly converts the 3 from an int to a float as part of the operation.
>> The type conversion isn't anywhere "on the cover" of the + operator. It's
>> implicit behavior.
>>
>> [1] Bjarne Stroustrup makes the observation in this talk
>>  at
>> 23:00.
>> ___
>> Python-ideas mailing list
>> Python-ideas@python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Nicholas Chammas
On Wed, Jul 25, 2018 at 6:36 PM David Mertz  wrote:

> The fact that a while bunch have people have commented on this subthread
> while not recognizing that the semantics of the '?.' and the if blocks are
> entirely different suggests the operators are but magnets.
>
> On Wed, Jul 25, 2018, 5:17 PM Nicholas Chammas 
> wrote:
>
>> On Mon, Jul 23, 2018 at 6:05 PM Giampaolo Rodola' 
>> wrote:
>>
>>> This:
>>>
>>> v = a?.b
>>>
>>> ...*implicitly* checks if value is not None [and continues execution].
>>> This:
>>>
>>> v = a
>>> if a.b is not None:
>>> v = a.b
>>>
>>> ...*explicitly* checks if value is not None and continues execution.
>>>
>>
Sorry, lazy reading on my part. I skimmed the expanded form assuming it was
correct. I think it should instead read `if a is not None: ...`.

Is that what you're getting at?
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread David Mertz
The fact that a while bunch have people have commented on this subthread
while not recognizing that the semantics of the '?.' and the if blocks are
entirely different suggests the operators are but magnets.

On Wed, Jul 25, 2018, 5:17 PM Nicholas Chammas 
wrote:

> On Mon, Jul 23, 2018 at 6:05 PM Giampaolo Rodola' 
> wrote:
>
>> This:
>>
>> v = a?.b
>>
>> ...*implicitly* checks if value is not None [and continues execution].
>> This:
>>
>> v = a
>> if a.b is not None:
>> v = a.b
>>
>> ...*explicitly* checks if value is not None and continues execution.
>>
>
> I think both of those are equally explicit. It's just that one notation is
> more concise than the other. Explicitness and conciseness are related but
> different things.
>
> When something is "explicit", as I understand it, that means it does what
> it says on the cover. There is no unstated behavior. The plain meaning of
> `v = a?.b` is that it expands to the longer form (`v = a; if a.b ...`), and
> it is just as explicit.
>
> This reminds me of something I read about once called Stroustrup's Rule
> 
>  [1]:
>
> > For new features, people insist on LOUD explicit syntax.
> > For established features, people want terse notation.
>
> I think the "explicit vs. implicit" part of this discussion is probably
> better expressed as a discussion about "loud vs. terse" syntax. None of the
> operators in PEP 505 have implicit behavior, to the best of my
> understanding. It's just that the operators are new and have terse
> spellings.
>
> As a point of comparison, I think a good example of implicit behavior is
> type coercion. When you ask Python to add an int to a float
>
> a = 3 + 4.5
>
> all that you've explicitly asked for is the addition. However, Python
> implicitly converts the 3 from an int to a float as part of the operation.
> The type conversion isn't anywhere "on the cover" of the + operator. It's
> implicit behavior.
>
> [1] Bjarne Stroustrup makes the observation in this talk
>  at
> 23:00.
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 505: None-aware operators

2018-07-25 Thread Abe Dillon
The problem here is not whether it's explicit. It's about Readability and
conciseness. Using symbols in place of words almost always harms
readability in favor of conciseness.

value = person.name if person.name else person

almost reads like english (aside from being a weird and totally uncommon
use case)

value = person?.name

Is a huge step towards the concise illegible soup of symbols that Perl is
famous for. It's a huge No from me.



On Wed, Jul 25, 2018 at 11:12 AM, Nicholas Chammas <
nicholas.cham...@gmail.com> wrote:

> On Mon, Jul 23, 2018 at 6:05 PM Giampaolo Rodola' 
> wrote:
>
>> This:
>>
>> v = a?.b
>>
>> ...*implicitly* checks if value is not None [and continues execution].
>> This:
>>
>> v = a
>> if a.b is not None:
>> v = a.b
>>
>> ...*explicitly* checks if value is not None and continues execution.
>>
>
> I think both of those are equally explicit. It's just that one notation is
> more concise than the other. Explicitness and conciseness are related but
> different things.
>
> When something is "explicit", as I understand it, that means it does what
> it says on the cover. There is no unstated behavior. The plain meaning of
> `v = a?.b` is that it expands to the longer form (`v = a; if a.b ...`), and
> it is just as explicit.
>
> This reminds me of something I read about once called Stroustrup's Rule
> 
>  [1]:
>
> > For new features, people insist on LOUD explicit syntax.
> > For established features, people want terse notation.
>
> I think the "explicit vs. implicit" part of this discussion is probably
> better expressed as a discussion about "loud vs. terse" syntax. None of the
> operators in PEP 505 have implicit behavior, to the best of my
> understanding. It's just that the operators are new and have terse
> spellings.
>
> As a point of comparison, I think a good example of implicit behavior is
> type coercion. When you ask Python to add an int to a float
>
> a = 3 + 4.5
>
> all that you've explicitly asked for is the addition. However, Python
> implicitly converts the 3 from an int to a float as part of the operation.
> The type conversion isn't anywhere "on the cover" of the + operator. It's
> implicit behavior.
>
> [1] Bjarne Stroustrup makes the observation in this talk
>  at
> 23:00.
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


  1   2   3   >