<p dir="ltr">On Sep 10, 2016 4:45 PM, "Guido van Rossum" <<a href="mailto:guido@python.org">guido@python.org</a>> wrote:<br>
><br>
> There seems to be a major misunderstanding here. A None-coalescing<br>
> operator is not for catching AttributeError, it's a shortcut similar<br>
> to "a or b" except that it checks for "a is None" rather than bool(a).</p>
<p dir="ltr">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.</p>
<p dir="ltr">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.</p>
<p dir="ltr">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.</p>
<p dir="ltr">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.</p>
<p dir="ltr">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.</p>
<p dir="ltr">><br>
> On Sat, Sep 10, 2016 at 4:38 PM, David Mertz <<a href="mailto:mertz@gnosis.cx">mertz@gnosis.cx</a>> wrote:<br>
> > Sorry, I sent this accidentally as private reply, then tried to fix it on<br>
> > phone.  The latter produced horrible formatting.  Please just read this<br>
> > version.<br>
> ><br>
> > On Sat, Sep 10, 2016 at 4:10 PM, Guido van Rossum <<a href="mailto:guido@python.org">guido@python.org</a>> wrote:<br>
> >><br>
> >> So you're offering `NoneCoalesce(x).bar` as less-ugly alternative to<br>
> >> `x?.bar`... Color me unconvinced.<br>
> ><br>
> ><br>
> > No, I'm offering a more realistic use pattern:<br>
> ><br>
> > for x in get_stuff():<br>
> ><br>
> >     x = NoneCoalesce(x)<br>
> ><br>
> >     # ... bunch of stuff with x ...<br>
> >     # ... more stuff with nested keys or attributes ...<br>
> ><br>
> >     x2 = x.foo<br>
> ><br>
> >     x3 = x.bar.baz[x2]<br>
> ><br>
> >     x4 = x(x.val)<br>
> ><br>
> >     result = x3(x4)<br>
> ><br>
> ><br>
> ><br>
> > As a less ugly alternative in the fairly uncommon case that you want None<br>
> > coalescing as the behavior of getting attributes, keys, call values, etc.<br>
> > that may or may not be available (AND where you don't want to wrap all of<br>
> > those access patterns in one try/except block).<br>
> ><br>
> > In contrast, the ugly version of even this pretty simple toy code with the<br>
> > hypothetical syntax would be:<br>
> ><br>
> > for x in get_stuff():<br>
> ><br>
> >     # ... bunch of stuff with x ...<br>
> ><br>
> >     # ... more stuff with nested keys or attributes ...<br>
> ><br>
> >     x2 = x?.foo<br>
> ><br>
> >     x3 = x?.bar?.baz?[x2]<br>
> ><br>
> >     x4 = x?(x?.val)<br>
> ><br>
> >     result = x3?(x4)<br>
> ><br>
> ><br>
> > This second case looks absolutely awful to me.  And real world uses, if<br>
> > implemented, would quickly get much worse than that.<br>
> ><br>
> > Yours, David...<br>
> ><br>
> > --<br>
> > Keeping medicines from the bloodstreams of the sick; food<br>
> > from the bellies of the hungry; books from the hands of the<br>
> > uneducated; technology from the underdeveloped; and putting<br>
> > advocates of freedom in prisons.  Intellectual property is<br>
> > to the 21st century what the slave trade was to the 16th.<br>
> ><br>
> ><br>
> ><br>
> > --<br>
> > Keeping medicines from the bloodstreams of the sick; food<br>
> > from the bellies of the hungry; books from the hands of the<br>
> > uneducated; technology from the underdeveloped; and putting<br>
> > advocates of freedom in prisons.  Intellectual property is<br>
> > to the 21st century what the slave trade was to the 16th.<br>
> ><br>
> > _______________________________________________<br>
> > Python-ideas mailing list<br>
> > <a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a><br>
> > <a href="https://mail.python.org/mailman/listinfo/python-ideas">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
> > Code of Conduct: <a href="http://python.org/psf/codeofconduct/">http://python.org/psf/codeofconduct/</a><br>
><br>
><br>
><br>
> --<br>
> --Guido van Rossum (<a href="http://python.org/~guido">python.org/~guido</a>)<br></p>