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

David Mertz mertz at gnosis.cx
Sat Sep 10 19:36:37 EDT 2016


On Sat, Sep 10, 2016 at 4:10 PM, Guido van Rossum <guido at python.org> 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.

>

> On Sat, Sep 10, 2016 at 4:06 PM, David Mertz <mertz at gnosis.cx> wrote:
> > Actually, I guess the example I liked was from the year ago
discussion.  And
> > it didn't do *exactly* what I think a wrapper should.  What I'd want
would
> > be like this:
> >
> > class NoneCoalesce(object):
> >     "Standard operations on object for 'is not None'"
> >     def __init__(self, obj):
> >         self.obj = obj
> >
> >     def __getattr__(self, name):
> >         try:
> >             return getattr(self.obj, name)
> >         except AttributeError:
> >             return NoneCoalesce(None)
> >
> >     def __getitem__(self, item):
> >         try:
> >             return self.obj[item]
> >         except (TypeError, KeyError):
> >             return NoneCoalesce(None)
> >
> >     def __call__(self, *args, **kwds):
> >         try:
> >             return self.obj(*args, **kwds)
> >         except TypeError:
> >             return NoneCoalesce(None)
> >
> >     def __bool__(self):
> >         return self.obj is not None
> >
> >     def __repr__(self):
> >         return "NoneCoalesce[%r]" % self.obj
> >
> >     def __str__(self):
> >         return "NoneCoalesce[%r]" % self.obj
> >
> >     def __len__(self):
> >         try:
> >             return len(self.obj)
> >         except TypeError:
> >             return 0
> >
> >
> > Then we might use it similar to this:
> >
> >>>> from boltons.dictutils import OrderedMultiDict
> >>>> from NoneCoalesce import NoneCoalesce
> >>>> omd = OrderedMultiDict()
> >>>> omd['a'] = 1
> >>>> omd['b'] = 2
> >>>> omd.add('a', 3)
> >>>> nc = NoneCoalesce(omd)
> >>>> nc or "Spanish Inquisition"
> > Out[8]: NoneCoalesce[OrderedMultiDict([('a', 1), ('b', 2), ('a', 3)])]
> >>>> nc.spam or "Spam"
> > Out[9]: 'Spam'
> >>>> nc['nope'].bar.baz()
> > Out[10]: NoneCoalesce[None]
> >>>> nc['a']
> > Out[11]: 3
> >>>> nc.getlist('a')
> > Out[12]: [1, 3]
> >
> >
> > Nothing special about boltons' OrderedMultiDict here, just something
I've
> > been playing with that has some distinctive methods.
> >
> > The idea is that we can easily have both "regular" behavior and None
> > coalescing just by wrapping any objects in a utility class... and
WITHOUT
> > adding ugly syntax.  I might have missed some corners where we would
want
> > behavior wrapped, but those shouldn't be that hard to add in principle.
> >
> > On Sat, Sep 10, 2016 at 3:21 PM, David Mertz <mertz at gnosis.cx> wrote:
> >>
> >> I find the '?.' syntax very ugly, much more so in the examples of
chained
> >> attributes.
> >>
> >> A much better way to handle the use case is to wrap objects in a class
> >> that gives this "propagating None" behavior with plain attribute
access. A
> >> nice implementation was presented in this thread.
> >>
> >>
> >> On Sep 10, 2016 3:16 PM, "Random832" <random832 at fastmail.com> wrote:
> >>>
> >>> On Sat, Sep 10, 2016, at 13:26, Guido van Rossum wrote:
> >>> > The way I recall it, we arrived at the perfect syntax (using ?) and
> >>> > semantics. The issue was purely strong hesitation about whether
> >>> > sprinkling ? all over your code is too ugly for Python
> >>>
> >>> I think that if there's "strong hesitation" about something being "too
> >>> ugly" it can't really be described as "the perfect syntax". IIRC there
> >>> were a couple alternatives being discussed that would have reduced the
> >>> number of question marks to one [or one per object which might be
None].
> >>> _______________________________________________
> >>> Python-ideas mailing list
> >>> Python-ideas at 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 at python.org
> > https://mail.python.org/mailman/listinfo/python-ideas
> > Code of Conduct: http://python.org/psf/codeofconduct/
>
>
>
> --
> --Guido van Rossum (python.org/~guido)


-- 
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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160910/bab68daa/attachment-0001.html>


More information about the Python-ideas mailing list