Re: [Python-ideas] Fwd: Null coalescing operator

2016-09-13 Thread MRAB

On 2016-09-13 16:27, Rob Cliffe wrote:



On 13/09/2016 12:37, Nick Coghlan wrote:

On 13 September 2016 at 21:15, Rob Cliffe  wrote:

On 13/09/2016 04:43, Guido van Rossum wrote:

Yeah, that's exactly my point. PEP 463 gives you a shorter way to
catch an exception, so it gives you less motivation to find a way to
write your code (or define your API) that doesn't involve catching
exceptions. But APIs involving exceptions are often inferior to APIs
that don't require exception catching. (Yes, I am aware of __next__()
raising StopIteration -- but that API design usually doesn't require
you to catch it.)


You surprise me.  I thought LBYL and EAFP were both approved Python idioms,
in some cases one being better, in some cases another, choice to be made on
the merits of each case (or the author's preference).  I certainly use both
(and sometimes time both to see which is faster).
Now it sounds as if you're trying to impose a style guide on the world by
discouraging the EAFP.  And wasn't the discussion general, not about APIs
specifically?

Which is preferable depends greatly on context of use, which is why
you'll find a lot of Python APIs offer both forms

My point exactly.  Random832 echoes my thoughts:

"Guido's argument here seems to be that exception-based EAFP is not
pythonic."


[snip]
I think the point is that exceptions are for, well, exceptional 
processing, not normal processing.


Code should be written on the assumption that everything works normally, 
e.g. division always returns a result.


_Occasionally_ division will fail, such as attempting to divide by zero, 
but that should be uncommon.


If something pretty much always succeeds, use an exception for failure, 
but if it sometimes succeeds and sometimes fails, check explicitly for 
success or failure.


___
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] Fwd: Null coalescing operator

2016-09-13 Thread Rob Cliffe



On 13/09/2016 12:37, Nick Coghlan wrote:

On 13 September 2016 at 21:15, Rob Cliffe  wrote:

On 13/09/2016 04:43, Guido van Rossum wrote:

Yeah, that's exactly my point. PEP 463 gives you a shorter way to
catch an exception, so it gives you less motivation to find a way to
write your code (or define your API) that doesn't involve catching
exceptions. But APIs involving exceptions are often inferior to APIs
that don't require exception catching. (Yes, I am aware of __next__()
raising StopIteration -- but that API design usually doesn't require
you to catch it.)


You surprise me.  I thought LBYL and EAFP were both approved Python idioms,
in some cases one being better, in some cases another, choice to be made on
the merits of each case (or the author's preference).  I certainly use both
(and sometimes time both to see which is faster).
Now it sounds as if you're trying to impose a style guide on the world by
discouraging the EAFP.  And wasn't the discussion general, not about APIs
specifically?

Which is preferable depends greatly on context of use, which is why
you'll find a lot of Python APIs offer both forms

My point exactly.  Random832 echoes my thoughts:

"Guido's argument here seems to be that exception-based EAFP is not
pythonic."


[snip]

However, blindly catching *all* exceptions from a complex
subexpression is rarely the right thing to do,

Of course.

  so APIs that only offer
"this may throw exceptions during normal operation under these
circumstances" without a convenience wrapper that does the exception
handling for you can end up being a pain to work with.

PEP 463 makes those APIs less painful to deal with, but at the cost of
encouraging overly broad exception handlers.
Why?  You can catch exactly the same (wide or narrow) range of 
exceptions in an exception-catching expression as you can in a 
try+except block.  Of course

result = (myList[0] except Exception: MyDefault)
is poor code (presumably it should have been written "except 
IndexError"), but so is

try:
result = myList[0]
except Exception:
result = MyDefault
ISTM you're giving an exception-catching dog a bad name and hanging 
him.  Or have I missed something?


And sorry to repeat myself, but we seemed to be having a *general* 
discussion about null-coalescing operators, which moved on to PEP 463, 
then suddenly Guido is talking about APIs.  A lot of the time when I'm 
coding, I'm not writing an API, just a program to get a job done.  No 
doubt, exceptions should be discouraged *in APIs*, but that doesn't make 
exceptions, or EAFP, a bad idea per se.


I really don't mean this post to sound hostile, and I'm sorry if it 
comes across a bit that way.  I'm just surprised at what I'm hearing, 
and to be honest, I have a soft spot for PEP 463.

Best wishes
Rob Cliffe
___
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] Fwd: Null coalescing operator

2016-09-13 Thread Random832
On Tue, Sep 13, 2016, at 08:44, Michel Desmoulin wrote:
> You won't see very complex usages, mostly things like:
> 
> val = foo[-1] except IndexError: "bar"
> doh = val.attr.other except AttributeError: "default"

It occurs to me that if lambda were more lightweight [whether it's the
syntax or the implementation that's the problem is unclear], not only
this but also the ternary operator could have been functions.

val = iexcept(lambda: foo[-1], IndexError, lambda: "bar")
___
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] Fwd: Null coalescing operator

2016-09-13 Thread Michel Desmoulin
I doubt very much it will be used for very complexe cases. Just like
comprehensions or ternary expressions, they are a good fit for some
specific use cases, and people will quickly catch on which one.

You rarely see nested comprehensions or ternary expressions while it's
possible to do so, because the Python communality values tend to limit
abuses.

It will be the same for this.

You won't see very complex usages, mostly things like:

val = foo[-1] except IndexError: "bar"
doh = val.attr.other except AttributeError: "default"

Those would already be coded with something similar (or maybe a chain of
getattr()) or next(iter()). It's not a huge risk.

But it's a huge convenience.


Le 13/09/2016 à 13:37, Nick Coghlan a écrit :
> On 13 September 2016 at 21:15, Rob Cliffe  wrote:
>> On 13/09/2016 04:43, Guido van Rossum wrote:
>>> Yeah, that's exactly my point. PEP 463 gives you a shorter way to
>>> catch an exception, so it gives you less motivation to find a way to
>>> write your code (or define your API) that doesn't involve catching
>>> exceptions. But APIs involving exceptions are often inferior to APIs
>>> that don't require exception catching. (Yes, I am aware of __next__()
>>> raising StopIteration -- but that API design usually doesn't require
>>> you to catch it.)
>>>
>> You surprise me.  I thought LBYL and EAFP were both approved Python idioms,
>> in some cases one being better, in some cases another, choice to be made on
>> the merits of each case (or the author's preference).  I certainly use both
>> (and sometimes time both to see which is faster).
>> Now it sounds as if you're trying to impose a style guide on the world by
>> discouraging the EAFP.  And wasn't the discussion general, not about APIs
>> specifically?
> 
> Which is preferable depends greatly on context of use, which is why
> you'll find a lot of Python APIs offer both forms - it's not *just* a
> matter of inheriting the exceptionless version from C, and then later
> adding a Python version that gives an exception instead of None or a
> user-supplied default value.
> 
> It's similar to why IEEE754 defines both quiet NaN *and* signalling
> NaN - which one you want depends on what you're doing.
> 
> In web servers, for example, you'll often have lots of fields where
> "not present" is a perfectly acceptable return value. For those, APIs
> that just return None for unknown entries are very handy, which is why
> SQL Alchemy offers both ".first()" and "one()", which mainly differ in
> how and when they throw an exception, rather than what they do when
> they succeed.
> 
> However, blindly catching *all* exceptions from a complex
> subexpression is rarely the right thing to do, so APIs that only offer
> "this may throw exceptions during normal operation under these
> circumstances" without a convenience wrapper that does the exception
> handling for you can end up being a pain to work with.
> 
> PEP 463 makes those APIs less painful to deal with, but at the cost of
> encouraging overly broad exception handlers. By contrast, fixing APIs
> on a case-by-case basis puts the design burden where it can do the
> most good: on the API designer, who can make the scope of the
> exception handling suitably narrow *inside* the API implementation,
> rather than being limited to wrapping the entire API call in
> try/except.
> 
> Cheers,
> Nick.
> 
> P.S. There are also some use cases where Look-Before-You-Leap is
> inherently subject to race conditions, and for those, exceptions are
> the only reliable signaling mechanism.
> 
___
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] Fwd: Null coalescing operator

2016-09-13 Thread Nick Coghlan
On 13 September 2016 at 21:15, Rob Cliffe  wrote:
> On 13/09/2016 04:43, Guido van Rossum wrote:
>> Yeah, that's exactly my point. PEP 463 gives you a shorter way to
>> catch an exception, so it gives you less motivation to find a way to
>> write your code (or define your API) that doesn't involve catching
>> exceptions. But APIs involving exceptions are often inferior to APIs
>> that don't require exception catching. (Yes, I am aware of __next__()
>> raising StopIteration -- but that API design usually doesn't require
>> you to catch it.)
>>
> You surprise me.  I thought LBYL and EAFP were both approved Python idioms,
> in some cases one being better, in some cases another, choice to be made on
> the merits of each case (or the author's preference).  I certainly use both
> (and sometimes time both to see which is faster).
> Now it sounds as if you're trying to impose a style guide on the world by
> discouraging the EAFP.  And wasn't the discussion general, not about APIs
> specifically?

Which is preferable depends greatly on context of use, which is why
you'll find a lot of Python APIs offer both forms - it's not *just* a
matter of inheriting the exceptionless version from C, and then later
adding a Python version that gives an exception instead of None or a
user-supplied default value.

It's similar to why IEEE754 defines both quiet NaN *and* signalling
NaN - which one you want depends on what you're doing.

In web servers, for example, you'll often have lots of fields where
"not present" is a perfectly acceptable return value. For those, APIs
that just return None for unknown entries are very handy, which is why
SQL Alchemy offers both ".first()" and "one()", which mainly differ in
how and when they throw an exception, rather than what they do when
they succeed.

However, blindly catching *all* exceptions from a complex
subexpression is rarely the right thing to do, so APIs that only offer
"this may throw exceptions during normal operation under these
circumstances" without a convenience wrapper that does the exception
handling for you can end up being a pain to work with.

PEP 463 makes those APIs less painful to deal with, but at the cost of
encouraging overly broad exception handlers. By contrast, fixing APIs
on a case-by-case basis puts the design burden where it can do the
most good: on the API designer, who can make the scope of the
exception handling suitably narrow *inside* the API implementation,
rather than being limited to wrapping the entire API call in
try/except.

Cheers,
Nick.

P.S. There are also some use cases where Look-Before-You-Leap is
inherently subject to race conditions, and for those, exceptions are
the only reliable signaling mechanism.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
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] Fwd: Null coalescing operator

2016-09-13 Thread Rob Cliffe

On 13/09/2016 04:43, Guido van Rossum wrote:

On Mon, Sep 12, 2016 at 5:45 PM, Rob Cliffe  wrote:


On 12/09/2016 16:37, Guido van Rossum wrote:

For the record, I still really don't like PEP 463. We should strive to
catch fewer exceptions, not make it easier to catch them.

Can you please clarify what you are saying in the last sentence?
The first time I read it, my brain parsed it as "People should raise fewer
exceptions, i.e. use LBYL less".

(If that means "Leap Before You Look", yes. :-)

I meant EAFP, but ! like your version! :-) Sorry for the confusion.



Later it seemed more likely that you meant "The set of exceptions we catch
in a specific piece of code should not be too large; we should only catch
those exceptions that we really mean to handle".
But perhaps you mean something else altogether?

Also I don't see the connection between the first sentence and the second.
Exception-catching expressions as per PEP 463 just give you a more concise
way of of doing something you can do with try+except.  Do you mean it would
make it easier to catch exceptions because you have to type fewer
characters, and that this would be a bad thing?

Yeah, that's exactly my point. PEP 463 gives you a shorter way to
catch an exception, so it gives you less motivation to find a way to
write your code (or define your API) that doesn't involve catching
exceptions. But APIs involving exceptions are often inferior to APIs
that don't require exception catching. (Yes, I am aware of __next__()
raising StopIteration -- but that API design usually doesn't require
you to catch it.)

You surprise me.  I thought LBYL and EAFP were both approved Python 
idioms, in some cases one being better, in some cases another, choice to 
be made on the merits of each case (or the author's preference).  I 
certainly use both (and sometimes time both to see which is faster).
Now it sounds as if you're trying to impose a style guide on the world 
by discouraging the EAFP.  And wasn't the discussion general, not about 
APIs specifically?

Best wishes,
Rob Cliffe
___
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] Fwd: Null coalescing operator

2016-09-13 Thread Nick Coghlan
On 13 September 2016 at 07:13, Paul Moore  wrote:
> If I understand the proposal, f is actually intended to be equivalent to:
>
> def f(spam):
> spam_val = spam()
> if spam_val is None:
> return None
> eggs_val = spam_val.eggs()
> if eggs_val is None:
> return None
> return eggs_val.ham
>
> Personally, I find it pretty worrying that there's this persistent
> confusion over what the proposed syntax means. Sure, it's explained in
> the PEP and proposal, but if it gets implemented it'll be in the docs.
> And yet people don't seem to read any of those - and their intuition
> of what the construct does is wrong.

Right, there are two quite reasonable interpretations for what a
conditional attribute lookup does, and the "catch and ignore
AttributeError" case is going to be more familiar to most Pythonistas,
as that's the way getattr() works when given a default value.

Consider the case of chained attribute lookup as a function using a
"None" default to getattr():

def attr_chain_abort_on_missing(base, *attrs):
result = base
for attr in attrs:
if result is None:
break
result = getattr(result, attr, None)
return result

vs the actually proposed semantics:

def attr_chain_abort_only on_none(base, *attrs):
result = base
for attr in attrs:
if result is None:
break
result = getattr(result, attr)
return result

In the latter version, AttibuteError escapes - it's only when the
original value is None, or an attribute exists and is None that the
iteration bails out early without raising an exception.

> IMO, the syntax may well be useful, but if we don't address the
> problem that what people *think* it means isn't what it actually
> means, then it'll do more harm than good.

Agreed, and I think a key indicator for that would be whether or not
people that saw:

result = obj?.first?.second?.third

agreed on whether or not it could raise AttributeError or TypeError.

Any prospective PhD students in the audience looking for a language
usability question to study before 3.7b1 rolls around in 2018? :)

Cheers,
Nick.

P.S. I'll note that the *upside* I see to (this part of) the proposal
is that it would implement a *very* fine-grained "is not None" check,
where the alternative in real code would often be an overly broad
exception handling clause, like:

try:
result = obj.first().second.third
except (TypeError, AttributeError):
return None

rather then actually spelling out the fine-grained checks properly.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
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] Fwd: Null coalescing operator

2016-09-12 Thread Rob Cliffe



On 13/09/2016 01:45, Rob Cliffe wrote:



On 12/09/2016 16:37, Guido van Rossum wrote:

For the record, I still really don't like PEP 463. We should strive to
catch fewer exceptions, not make it easier to catch them.

Can you please clarify what you are saying in the last sentence?
The first time I read it, my brain parsed it as "People should raise 
fewer exceptions, i.e. use LBYL less".

Typo: I meant EAFP not LBYL - sorry!
Later it seemed more likely that you meant "The set of exceptions we 
catch in a specific piece of code should not be too large; we should 
only catch those exceptions that we really mean to handle".

But perhaps you mean something else altogether?

Also I don't see the connection between the first sentence and the 
second.  Exception-catching expressions as per PEP 463 just give you a 
more concise way of of doing something you can do with try+except.  Do 
you mean it would make it easier to catch exceptions because you have 
to type fewer characters, and that this would be a bad thing?

Thanks,
Rob Cliffe

___
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] Fwd: Null coalescing operator

2016-09-12 Thread Ethan Furman

On 09/12/2016 08:37 AM, Guido van Rossum wrote:


For the record, I still really don't like PEP 463. We should strive to
catch fewer exceptions, not make it easier to catch them.


I certainly agree with the first part, slightly reworded: we should strive to 
generate fewer exceptions that we have to catch.

I disagree with the second part:  being able to condense four lines of code (1 
for try, 1 for except, 1 for the attempt, and 1 for recovery) in to one line of 
code seems like a win.  I know I find it frustrating when my choice is between 
the 4-line boiler-plate try/except, or an equally verbose and ugly multi-line 
non-exception generating stanza.

Anyway, my two cents worth.  If you collect them all for this subject I think I 
owe you a dime.  ;)

--
~Ethan~
___
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] Fwd: Null coalescing operator

2016-09-12 Thread Paul Moore
On 12 September 2016 at 21:47, Eric Snow  wrote:
> Note that there's a subtle difference here when multiple lookups are
> involved.  Given:
>
> def f(spam):
> return spam().eggs().ham
>
> With null-coalescing:
>
> def f(spam):
> return spam()?.eggs()?.ham
>
> This is roughly equivalent to:
>
>def f(spam):
> _spam = spam()
> try:
> eggs = _spam.eggs
> except AttributeError:
> return None
> _eggs = eggs()
> try:
> return _eggs.ham
> except AttributeError:
> return None

>From previous explanations in this thread, that's *not* the behaviour at all.

If I understand the proposal, f is actually intended to be equivalent to:

def f(spam):
spam_val = spam()
if spam_val is None:
return None
eggs_val = spam_val.eggs()
if eggs_val is None:
return None
return eggs_val.ham

Personally, I find it pretty worrying that there's this persistent
confusion over what the proposed syntax means. Sure, it's explained in
the PEP and proposal, but if it gets implemented it'll be in the docs.
And yet people don't seem to read any of those - and their intuition
of what the construct does is wrong.

IMO, the syntax may well be useful, but if we don't address the
problem that what people *think* it means isn't what it actually
means, then it'll do more harm than good.

Paul
___
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] Fwd: Null coalescing operator

2016-09-12 Thread Eric Snow
On Mon, Sep 12, 2016 at 1:05 AM, Michel Desmoulin
 wrote:
> There is also an alternative to this operator, and it's allowing a
> shortcut to do:
>
> try:
> val = do_thing()
> except ThingError:
> val = "default"
>
> In the form of:
>
> val = do_thing() except ThingError: "default"

Note that there's a subtle difference here when multiple lookups are
involved.  Given:

def f(spam):
return spam().eggs().ham

With null-coalescing:

def f(spam):
return spam()?.eggs()?.ham

This is roughly equivalent to:

   def f(spam):
_spam = spam()
try:
eggs = _spam.eggs
except AttributeError:
return None
_eggs = eggs()
try:
return _eggs.ham
except AttributeError:
return None

With PEP 463 it doesn't work out so well.  The "obvious" spelling would be:

def f(spam):
return (spam().eggs().ham except AttributeError: None)

This is roughly equivalent to:

def f(spam):
try:
return spam().eggs().ham
except AttributeError:
return None

Note how it's different. For one thing, it could mask AttributeError
coming from the calls.  For another, you no longer explicitly identify
which lookups to handle.  I would expect both to lead to subtle bugs,
whereas with null-coalescing you don't have those problems.

-eric
___
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] Fwd: Null coalescing operator

2016-09-12 Thread Chris Angelico
On Tue, Sep 13, 2016 at 12:03 AM, Rob Cliffe  wrote:
> Assuming you can't break existing code that already traps TypeError,
> AttributeError, etc., I don't see how you can do this without
> having separated kinds of NoneError which were subclasses of TypeError,
> AttributeError, etc.

class NoneError(Exception): pass
class TypeNoneError(TypeError, NoneError): pass
class AttributeNoneError(AttributeError, NoneError): pass

Now you can catch NoneError to catch None.xyz, or AttributeError to
catch foo.xyz for any foo.

I don't think it's good, but it's possible.

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] Fwd: Null coalescing operator

2016-09-12 Thread Rob Cliffe



On 12/09/2016 08:05, Michel Desmoulin wrote:

I messed up my answer and replied to one person instead of the list, so
I'll post it again.

There is also an alternative to this operator, and it's allowing a
shortcut to do:

try:
 val = do_thing()
except ThingError:
 val = "default"

In the form of:

val = do_thing() except ThingError: "default"

I was debated, and rejected, but I feel like mentioning it again because
it has some strong benefits.

First, it handles the null coalescing very quite well:

val = obj.foo.bar.hey except AttributeError: "default"

But it also can deal with many common operations in Python without the
need to add more operators or variants:

val = my_list[0] except IndexError: "default"

val = iterable[0] except TypeError: next(iter(iterable))

val = int(param) except ValueError: man.nan

It's quite readable, in the same vein of val = foo if bar else
"default", but also familiar since it's using known keyword. And it
doesn't require to add a new operator support in the parser.

Another serious benefits is that it fits current use cases, AND futur
use cases. Indeed, since it leverages Python exception mechanism, any
lib implementing a clean error model can immediately let the users
benefit from it without having to implement, tests and document lots of
helper methods with "default" keywords and the like, while not being
limited to a set of values some operators would only care about, such as
None.

Plus, since EAFP is a popular and handy pattern, it makes sense.

At last, it has the same characteristic as the null coalescing operator:
it's lazy, and hence has a small performance interest too compared to
functional equivalent.

Did I mention it's also easy to expend to a full try/except when you
need something more complicated ? And then you benefit from else and
finally immediately.

I already have many code that would benefit from such a syntax, and I'd
like to hear again what you think about it.



+1, you're preaching to the converted.
This is PEP 463, "Exception-catching expressions".
Except that the PEP required parentheses around a whole 
exception-catching expression, for reasons that are not clear to me, i.e.

val = (my_list[0] except IndexError: "default")
rather than
val = my_list[0] except IndexError: "default"
Rob Cliffe



___
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] Fwd: Null coalescing operator

2016-09-12 Thread Ivan Levkivskyi
On 12 September 2016 at 09:05, Michel Desmoulin 
wrote:

> In the form of:
>
> val = do_thing() except ThingError: "default"
>
> [...]

>
> But it also can deal with many common operations in Python without the
> need to add more operators or variants:
>
> val = my_list[0] except IndexError: "default"
>
> val = iterable[0] except TypeError: next(iter(iterable))
>
> val = int(param) except ValueError: man.nan
>

 I like this idea, I would propose a (maybe crazy) addition to it. What
about a special exception NoneError, that will catch TypeError,
AttributeError etc. but only when it was caused by None(),
None.attr, None[1], etc. With this one can write:

x = a.b()[0] except NoneError: 'default'

without a risk of catching other (unrelated) exceptions.

--
Ivan
___
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] Fwd: Null coalescing operator

2016-09-12 Thread Ethan Furman

On 09/12/2016 12:05 AM, Michel Desmoulin wrote:


There is also an alternative to this operator, and it's allowing a
shortcut to do:

try:
 val = do_thing()
except ThingError:
 val = "default"

In the form of:

val = do_thing() except ThingError: "default"

I was debated, and rejected, but I feel like mentioning it again because
it has some strong benefits.


+1

There are many places in my code where this would clean things up a bit.  Not 
having it is like not having list comps or not having the ternary if-else -- 
possible, but it would be much nicer to have it.

--
~Ethan~
___
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] Fwd: Null coalescing operator

2016-09-11 Thread Guido van Rossum
On Sun, Sep 11, 2016 at 6:00 PM, David Mertz  wrote:
> None if a is None else a.foo

This is the crux of the matter to me. It's just too verbose, and the
`if` and `else` keywords are lost in the noise of all the other words
on the line. Plus the big win when it applies) is that if `a` is in
fact something more complex, like `f(a)`, repeating it twice sounds
like a performance penalty, and that's where `f(a)?.foo` really
shines.

-- 
--Guido van Rossum (python.org/~guido)
___
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] Fwd: Null coalescing operator

2016-09-11 Thread Guido van Rossum
On Sun, Sep 11, 2016 at 12:44 PM, Daniel Moisset
 wrote:
> Both this discussion, PEP 505, and the one a year ago, tend to mix up 2
> related but separate proposals:

I don't think there's that much of a mix-up. PEP 505 clearly describes
each proposal separately and even gives a choice to accept or reject
each one separately.

> (A) Add a None-coalescing operator (like C# a ?? b, what you would write in
> Python as "a or b" if it didn't have the falsy gotcha)

https://www.python.org/dev/peps/pep-0505/#none-coalescing-operator

> (B) Add some None-aware navigation operators ( The "?.", "?()", "?[]", or
> what you would write in python as "a and a.attribute" if it didn't have the
> falsy gotcha)

https://www.python.org/dev/peps/pep-0505/#none-aware-attribute-access-operator

> Both are things that can be already done in python, so the purpose here is
> to add some convenience (aka "syntax sugar"). IMO, this kind of syntax sugar
> proposals should be weighed with the frequency of the coding pattern where
> the sugar can be applied. And from the stats presented in PEP-505 (B) is one
> order of magnitude less usual than (A); that matches most of the examples I
> see in the threads and FWIW my personal experience.

I can't argue here yet. Honestly I looked at some examples; for those
where it wasn't instantly clear that a None-coalescing operator would
*not* help, I found it hard to figure out how to rewrite it. E.g. this
one -- quick, is there a better way?

  return "Illegal Argument" + (self.message is not None and (": " +
self.message) or "")

I think the answer is, if we had both None-coalescing (??) and
None-severing (!!) it could be written as follows:

  return "Illegal Argument" + ((self.message !! (": " + self.message)) ?? "")

but it took me way too long to prove that to myself.

> So, as a counterproposal I would like to suggest:
>
> * Add an "a ?? b" operator which is equivalent to "a if a is None else b"
> (but evaluating a once)

> * Do not add none-aware navigation; in the less usual scenario where you
> need to do it AND ALSO the "and" operator is not usable (it frequently is,
> given that by default classes are truish), well, you can use a ternary
> operator

Honestly the one thing that makes `?.` attractive is that it's easier
than the None-coalescing and -severing operators to grasp at an
intuitive level. If "foo.bar" raises "AttributeError: 'NoneType'
object has no attribute 'foo'" then try again with "foo?.bar". It's
surprising how often that will work!

> * I don't care if it's an alternate syntax (I'm surprised nobody suggested
> "||" which is also used in other languages for similar purpose)

Interestingly, after analyzing the above example I desperately want to
write it as

  return "Illegal Argument" + (self.message && (": " + self.message) || "")

Note that I already know the relative priorities of && and ||, so I
can drop a set of parentheses.

> Would this satisfy most of the people requesting this? (and, would it
> satisfy the people making the decision?)

Personally, after the above example, I'm less excited about ??/!! or
||/&&, and more excited about `?.` -- so it doesn't satisfy me.

-- 
--Guido van Rossum (python.org/~guido)
___
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] Fwd: Null coalescing operator

2016-09-11 Thread Daniel Moisset
Both this discussion, PEP 505, and the one a year ago, tend to mix up 2
related but separate proposals:
w
(A) Add a None-coalescing operator (like C# a ?? b, what you would write in
Python as "a or b" if it didn't have the falsy gotcha)
(B) Add some None-aware navigation operators ( The "?.", "?()", "?[]", or
what you would write in python as "a and a.attribute" if it didn't have the
falsy gotcha)

Both are things that can be already done in python, so the purpose here is
to add some convenience (aka "syntax sugar"). IMO, this kind of syntax
sugar proposals should be weighed with the frequency of the coding pattern
where the sugar can be applied. And from the stats presented in PEP-505 (B)
is one order of magnitude less usual than (A); that matches most of the
examples I see in the threads and FWIW my personal experience.

So, as a counterproposal I would like to suggest:

* Add an "a ?? b" operator which is equivalent to "a if a is None else b"
(but evaluating a once)
* Do not add none-aware navigation; in the less usual scenario where you
need to do it AND ALSO the "and" operator is not usable (it frequently is,
given that by default classes are truish), well, you can use a ternary
operator
* I don't care if it's an alternate syntax (I'm surprised nobody suggested
"||" which is also used in other languages for similar purpose)

Would this satisfy most of the people requesting this? (and, would it
satisfy the people making the decision?)



On Sun, Sep 11, 2016 at 4:45 AM, Bruce Leban  wrote:

>
> On Sat, Sep 10, 2016 at 6:02 PM, David Mertz  wrote:
>
>> What I was getting at with "essentially" was that it would *do the same
>> thing* that an AttributeError does.  That is, if `x.foo` can't be evaluated
>> (i.e. x doesn't have an attribute 'foo'), then access is informally "an
>> error."  The hypothetical "x?.foo" catches that "error" and substitutes a
>> different value.  The particular implementation under-the-hood is less
>> important for most programmers who might use the construct (and I think
>> documentation would actually give an informal equivalent as something
>> similar to what I put in the NoneCoalesce class).
>>
>
> That's not a good way to think about it. This new operator is only
> checking for None and not actually checking for AttributeErrors. Consider:
>
> (3).x# AttributeError
> {}.x # AttributeError
>
> None.x   # AttributeError
>
>
> (3)?.x   # still AttributeError
>
> {}?.x# still AttributeError
>
> None?.x  # None
>
>
> And also:
>
> None.__class__   # 
>
> None?.__class__  # None
>
>
> And it's certainly not the case that those values don't accept any
> attributes:
>
> (3).real# 3
> {}.values   # 
> None.__class__  #
>
> --- Bruce
> Check out my puzzle book and get it free here:
> http://J.mp/ingToConclusionsFree (available on iOS)
>
>
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 
Daniel F. Moisset - UK Country Manager
www.machinalis.com
Skype: @dmoisset
___
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] Fwd: Null coalescing operator

2016-09-10 Thread Bruce Leban
On Sat, Sep 10, 2016 at 6:02 PM, David Mertz  wrote:

> What I was getting at with "essentially" was that it would *do the same
> thing* that an AttributeError does.  That is, if `x.foo` can't be evaluated
> (i.e. x doesn't have an attribute 'foo'), then access is informally "an
> error."  The hypothetical "x?.foo" catches that "error" and substitutes a
> different value.  The particular implementation under-the-hood is less
> important for most programmers who might use the construct (and I think
> documentation would actually give an informal equivalent as something
> similar to what I put in the NoneCoalesce class).
>

That's not a good way to think about it. This new operator is only checking
for None and not actually checking for AttributeErrors. Consider:

(3).x# AttributeError
{}.x # AttributeError

None.x   # AttributeError


(3)?.x   # still AttributeError

{}?.x# still AttributeError

None?.x  # None


And also:

None.__class__   # 

None?.__class__  # None


And it's certainly not the case that those values don't accept any
attributes:

(3).real# 3
{}.values   # 
None.__class__  #

--- Bruce
Check out my puzzle book and get it free here:
http://J.mp/ingToConclusionsFree (available on iOS)
___
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] Fwd: Null coalescing operator

2016-09-10 Thread Random832
On Sat, Sep 10, 2016, at 19:38, David Mertz wrote:
> x2 = x?.foo
> 
> x3 = x?.bar?.baz?[x2]

A. if you're doing three different things with x, why are you using this
instead of wrapping it in an if statement?

B. Under some of the proposals, unless x.bar might be None independently
of x not being None, this would just be "x?.bar.baz[x2]
 
> x4 = x?(x?.val)

C. Under some of the proposals, the inner contents of the call brackets
aren't evaluated if x is None, so you don't need to use x?.val here.

> result = x3?(x4)
___
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] Fwd: Null coalescing operator

2016-09-10 Thread David Mertz
How much of the time is a branch of the None check a single fallback value
or attribute access versus how often a suite of statements within the
not-None branch?

I definitely check for None very often also. I'm curious what the breakdown
is in code I work with.

On Sep 10, 2016 7:10 PM, "Guido van Rossum"  wrote:

> To the contrary. I read and write code that performs explicit checks
> for None all the time. Catching AttributeError is often a code smell
> or at least a measure of last resort.
>
> On Sat, Sep 10, 2016 at 6:46 PM, David Mertz  wrote:
> > Ok, I have been thinking of the behavior too broadly. I realize now that
> > `x?.foo` might still simply raise an AttributeError if x is neither None
> nor
> > a thing with a foo attribute.
> >
> > The class I wrote is definitely too aggressive for the behavior
> described.
> > On the other hand, by being narrower in behavior there feels like even
> less
> > motivation for new syntax.
> >
> >
> > On Sep 10, 2016 6:29 PM, "MRAB"  wrote:
> >>
> >> On 2016-09-11 02:02, David Mertz wrote:
> >>>
> >>> On Sat, Sep 10, 2016 at 5:23 PM, Guido van Rossum  >>> > wrote:
> >>>
> >>> No. PEP 505 actually solves the problem without ever catching
> >>> AttributeError. Please read it.
> >>>
> >>>
> >>> I read it again (I did a year ago, but reviewed it now).  I hadn't been
> >>> thinking that the *mechanism* of a new None-coalescing operator would
> >>> actually be catching an exception.  It could (and should) work
> >>> differently if it becomes syntax.
> >>>
> >>> What I was getting at with "essentially" was that it would *do the same
> >>> thing* that an AttributeError does.  That is, if `x.foo` can't be
> >>> evaluated (i.e. x doesn't have an attribute 'foo'), then access is
> >>> informally "an error."  The hypothetical "x?.foo" catches that "error"
> >>> and substitutes a different value.  The particular implementation
> >>> under-the-hood is less important for most programmers who might use the
> >>> construct (and I think documentation would actually give an informal
> >>> equivalent as something similar to what I put in the NoneCoalesce
> class).
> >>>
> >> x?.foo would lookup attribute 'foo' _unless_ x was None, in which case
> it
> >> would return None. It's simply:
> >>
> >> None if x is None else x.foo
> >>
> >> This means that None?.__str__() would return None, not 'None'. (None has
> >> an attribute called '__str__', and None.__str__() returns 'None', but it
> >> would not be looked up because None is, well, 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/
> >
> >
> > ___
> > Python-ideas mailing list
> > Python-ideas@python.org
> > https://mail.python.org/mailman/listinfo/python-ideas
> > Code of Conduct: http://python.org/psf/codeofconduct/
>
>
>
> --
> --Guido van Rossum (python.org/~guido)
>
___
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] Fwd: Null coalescing operator

2016-09-10 Thread Guido van Rossum
To the contrary. I read and write code that performs explicit checks
for None all the time. Catching AttributeError is often a code smell
or at least a measure of last resort.

On Sat, Sep 10, 2016 at 6:46 PM, David Mertz  wrote:
> Ok, I have been thinking of the behavior too broadly. I realize now that
> `x?.foo` might still simply raise an AttributeError if x is neither None nor
> a thing with a foo attribute.
>
> The class I wrote is definitely too aggressive for the behavior described.
> On the other hand, by being narrower in behavior there feels like even less
> motivation for new syntax.
>
>
> On Sep 10, 2016 6:29 PM, "MRAB"  wrote:
>>
>> On 2016-09-11 02:02, David Mertz wrote:
>>>
>>> On Sat, Sep 10, 2016 at 5:23 PM, Guido van Rossum >> > wrote:
>>>
>>> No. PEP 505 actually solves the problem without ever catching
>>> AttributeError. Please read it.
>>>
>>>
>>> I read it again (I did a year ago, but reviewed it now).  I hadn't been
>>> thinking that the *mechanism* of a new None-coalescing operator would
>>> actually be catching an exception.  It could (and should) work
>>> differently if it becomes syntax.
>>>
>>> What I was getting at with "essentially" was that it would *do the same
>>> thing* that an AttributeError does.  That is, if `x.foo` can't be
>>> evaluated (i.e. x doesn't have an attribute 'foo'), then access is
>>> informally "an error."  The hypothetical "x?.foo" catches that "error"
>>> and substitutes a different value.  The particular implementation
>>> under-the-hood is less important for most programmers who might use the
>>> construct (and I think documentation would actually give an informal
>>> equivalent as something similar to what I put in the NoneCoalesce class).
>>>
>> x?.foo would lookup attribute 'foo' _unless_ x was None, in which case it
>> would return None. It's simply:
>>
>> None if x is None else x.foo
>>
>> This means that None?.__str__() would return None, not 'None'. (None has
>> an attribute called '__str__', and None.__str__() returns 'None', but it
>> would not be looked up because None is, well, 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/
>
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/



-- 
--Guido van Rossum (python.org/~guido)
___
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] Fwd: Null coalescing operator

2016-09-10 Thread David Mertz
Ok, I have been thinking of the behavior too broadly. I realize now that
`x?.foo` might still simply raise an AttributeError if x is neither None
nor a thing with a foo attribute.

The class I wrote is definitely too aggressive for the behavior described.
On the other hand, by being narrower in behavior there feels like even less
motivation for new syntax.

On Sep 10, 2016 6:29 PM, "MRAB"  wrote:

> On 2016-09-11 02:02, David Mertz wrote:
>
>> On Sat, Sep 10, 2016 at 5:23 PM, Guido van Rossum > > wrote:
>>
>> No. PEP 505 actually solves the problem without ever catching
>> AttributeError. Please read it.
>>
>>
>> I read it again (I did a year ago, but reviewed it now).  I hadn't been
>> thinking that the *mechanism* of a new None-coalescing operator would
>> actually be catching an exception.  It could (and should) work
>> differently if it becomes syntax.
>>
>> What I was getting at with "essentially" was that it would *do the same
>> thing* that an AttributeError does.  That is, if `x.foo` can't be
>> evaluated (i.e. x doesn't have an attribute 'foo'), then access is
>> informally "an error."  The hypothetical "x?.foo" catches that "error"
>> and substitutes a different value.  The particular implementation
>> under-the-hood is less important for most programmers who might use the
>> construct (and I think documentation would actually give an informal
>> equivalent as something similar to what I put in the NoneCoalesce class).
>>
>> x?.foo would lookup attribute 'foo' _unless_ x was None, in which case it
> would return None. It's simply:
>
> None if x is None else x.foo
>
> This means that None?.__str__() would return None, not 'None'. (None has
> an attribute called '__str__', and None.__str__() returns 'None', but it
> would not be looked up because None is, well, 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/
>
___
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] Fwd: Null coalescing operator

2016-09-10 Thread David Mertz
On Sat, Sep 10, 2016 at 5:23 PM, Guido van Rossum  wrote:

> No. PEP 505 actually solves the problem without ever catching
> AttributeError. Please read it.
>

I read it again (I did a year ago, but reviewed it now).  I hadn't been
thinking that the *mechanism* of a new None-coalescing operator would
actually be catching an exception.  It could (and should) work differently
if it becomes syntax.

What I was getting at with "essentially" was that it would *do the same
thing* that an AttributeError does.  That is, if `x.foo` can't be evaluated
(i.e. x doesn't have an attribute 'foo'), then access is informally "an
error."  The hypothetical "x?.foo" catches that "error" and substitutes a
different value.  The particular implementation under-the-hood is less
important for most programmers who might use the construct (and I think
documentation would actually give an informal equivalent as something
similar to what I put in the NoneCoalesce class).


-- 
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] Fwd: Null coalescing operator

2016-09-10 Thread Guido van Rossum
No. PEP 505 actually solves the problem without ever catching
AttributeError. Please read it.

On Sat, Sep 10, 2016 at 5:15 PM, David Mertz  wrote:
> On Sep 10, 2016 4:45 PM, "Guido van Rossum"  wrote:
>>
>> There seems to be a major misunderstanding here. A None-coalescing
>> operator is not for catching AttributeError, it's a shortcut similar
>> to "a or b" except that it checks for "a is None" rather than bool(a).
>
> That's exactly what the wrapper does. Except it converts all the regular
> operators into their None-coalescing versions by putting the extra checks
> into the wrapped object itself.
>
> Now admittedly, this DOES mean that the behavior of operations is somewhat
> different depending on whether they are wrapped objects or not. False-like
> is a different thing than None-like.
>
> This really MUST BE essentially a way a catching AttributeErrors though.
> With the proposed syntax 'x?.foo?.bar' will resolve even if x has no 'foo'.
> So 'x?.'foo' has to be something special. I guess that special thing could
> be a 3.7-style None that responds to new operators, but that's essentially
> still *wrapping* a 3.6-style None.
>
> In my mind, as I say, the question marks look ugly, especially when repeated
> in chained operations (attribute, call, item get). But even if they didn't
> feel bad visually, I don't believe the use case is common enough to warrant
> dedicated syntax. Even if my keyboard had some character I thought was
> beautiful and intuitive for that meaning, it's still an extra cognitive
> burden to distinguish the plain from None-coalescing versions of every
> operation, especially for learners.
>
> Another problem is that the question mark still doesn't actually get the
> special 'a or b' behavior. For that you still need 'a if a is not None else
> b'. Or I guess, in concept, 'a ?or b'. For what it's worth, the wrapper
> gives you the special 'a or b' semantics by casting non-Nones as truthy...
> But again, 'a' has to have been wrapped first.
>
>>
>> On Sat, Sep 10, 2016 at 4:38 PM, David Mertz  wrote:
>> > Sorry, I sent this accidentally as private reply, then tried to fix it
>> > on
>> > phone.  The latter produced horrible formatting.  Please just read this
>> > version.
>> >
>> > On Sat, Sep 10, 2016 at 4:10 PM, Guido van Rossum 
>> > wrote:
>> >>
>> >> So you're offering `NoneCoalesce(x).bar` as less-ugly alternative to
>> >> `x?.bar`... Color me unconvinced.
>> >
>> >
>> > No, I'm offering a more realistic use pattern:
>> >
>> > for x in get_stuff():
>> >
>> > x = NoneCoalesce(x)
>> >
>> > # ... bunch of stuff with x ...
>> > # ... more stuff with nested keys or attributes ...
>> >
>> > x2 = x.foo
>> >
>> > x3 = x.bar.baz[x2]
>> >
>> > x4 = x(x.val)
>> >
>> > result = x3(x4)
>> >
>> >
>> >
>> > As a less ugly alternative in the fairly uncommon case that you want
>> > None
>> > coalescing as the behavior of getting attributes, keys, call values,
>> > etc.
>> > that may or may not be available (AND where you don't want to wrap all
>> > of
>> > those access patterns in one try/except block).
>> >
>> > In contrast, the ugly version of even this pretty simple toy code with
>> > the
>> > hypothetical syntax would be:
>> >
>> > for x in get_stuff():
>> >
>> > # ... bunch of stuff with x ...
>> >
>> > # ... more stuff with nested keys or attributes ...
>> >
>> > x2 = x?.foo
>> >
>> > x3 = x?.bar?.baz?[x2]
>> >
>> > x4 = x?(x?.val)
>> >
>> > result = x3?(x4)
>> >
>> >
>> > This second case looks absolutely awful to me.  And real world uses, if
>> > implemented, would quickly get much worse than that.
>> >
>> > Yours, David...
>> >
>> > --
>> > 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.
>> >
>> >
>> >
>> > --
>> > 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/
>>
>>
>>
>> --
>> --Guido van Rossum (python.org/~guido)



-- 
--Guido van Rossum (python.org/~guido)
___
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] Fwd: Null coalescing operator

2016-09-10 Thread Guido van Rossum
There seems to be a major misunderstanding here. A None-coalescing
operator is not for catching AttributeError, it's a shortcut similar
to "a or b" except that it checks for "a is None" rather than bool(a).

On Sat, Sep 10, 2016 at 4:38 PM, David Mertz  wrote:
> Sorry, I sent this accidentally as private reply, then tried to fix it on
> phone.  The latter produced horrible formatting.  Please just read this
> version.
>
> On Sat, Sep 10, 2016 at 4:10 PM, Guido van Rossum  wrote:
>>
>> So you're offering `NoneCoalesce(x).bar` as less-ugly alternative to
>> `x?.bar`... Color me unconvinced.
>
>
> No, I'm offering a more realistic use pattern:
>
> for x in get_stuff():
>
> x = NoneCoalesce(x)
>
> # ... bunch of stuff with x ...
> # ... more stuff with nested keys or attributes ...
>
> x2 = x.foo
>
> x3 = x.bar.baz[x2]
>
> x4 = x(x.val)
>
> result = x3(x4)
>
>
>
> As a less ugly alternative in the fairly uncommon case that you want None
> coalescing as the behavior of getting attributes, keys, call values, etc.
> that may or may not be available (AND where you don't want to wrap all of
> those access patterns in one try/except block).
>
> In contrast, the ugly version of even this pretty simple toy code with the
> hypothetical syntax would be:
>
> for x in get_stuff():
>
> # ... bunch of stuff with x ...
>
> # ... more stuff with nested keys or attributes ...
>
> x2 = x?.foo
>
> x3 = x?.bar?.baz?[x2]
>
> x4 = x?(x?.val)
>
> result = x3?(x4)
>
>
> This second case looks absolutely awful to me.  And real world uses, if
> implemented, would quickly get much worse than that.
>
> Yours, David...
>
> --
> 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.
>
>
>
> --
> 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/



-- 
--Guido van Rossum (python.org/~guido)
___
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] Fwd: Null coalescing operator

2016-09-10 Thread David Mertz
Sorry, I sent this accidentally as private reply, then tried to fix it on
phone.  The latter produced horrible formatting.  Please just read this
version.

On Sat, Sep 10, 2016 at 4:10 PM, Guido van Rossum  wrote:

> So you're offering `NoneCoalesce(x).bar` as less-ugly alternative to
> `x?.bar`... Color me unconvinced.
>

No, I'm offering a more realistic use pattern:

for x in get_stuff():

x = NoneCoalesce(x)

# ... bunch of stuff with x ...
# ... more stuff with nested keys or attributes ...

x2 = x.foo

x3 = x.bar.baz[x2]

x4 = x(x.val)

result = x3(x4)



As a less ugly alternative in the fairly uncommon case that you want None
coalescing as the behavior of getting attributes, keys, call values, etc.
that may or may not be available (AND where you don't want to wrap all of
those access patterns in one try/except block).

In contrast, the ugly version of even this pretty simple toy code with the
hypothetical syntax would be:

for x in get_stuff():

# ... bunch of stuff with x ...

# ... more stuff with nested keys or attributes ...

x2 = x?.foo

x3 = x?.bar?.baz?[x2]

x4 = x?(x?.val)

result = x3?(x4)


This second case looks absolutely awful to me.  And real world uses, if
implemented, would quickly get much worse than that.

Yours, David...

-- 
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.



-- 
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/