[Python-ideas] Using "||" (doubled pipe) as the null coalescing operator?

Ryan Gonzalez rymg19 at gmail.com
Wed Sep 23 16:37:37 CEST 2015

*cough* Ruby and Perl *cough*

Ruby has two 'or' operators. One is used normally:

myval = a == 1 || a == 2
# same as
myval = (a == 1 || a == 2)

The other one is a bit different:

myval = a == 1 or a == 2
# same as
(myval = a == 1) or (a == 2)

It's used for simple nil and false elision, since Ruby has a stricter concept of falseness than Python.

But it's a bug magnet!! That's what I hated about Ruby. Type the wrong operator and get a hidden error.

Sometimes, when I code in C++ a lot and then do something in Python, I'll do:

if a || b:

Then I realize my mistake and fix it.

BUT, with this change, it wouldn't be a mistake. It would just do something entirely different.

On September 23, 2015 4:00:41 AM CDT, Nick Coghlan <ncoghlan at gmail.com> wrote:
>This may just be my C programmer brain talking, but reading the
>examples in PEP 505 makes me think of the existing use of "|" as the
>bitwise-or operator in both Python and C, and "||" as the logical-or
>operator in C.
>Using || for None-coalescence would still introduce a third "or"
>variant into Python as PEP 505 proposes (for good reasons), but
>without introducing a new symbolic character that relates to "OR"
>    x | y: bitwise OR (doesn't short circuit)
>    x or y: logical OR (short circuits based on bool(x))
>    x || y: logical OR (short circuits based on "x is not None")
>(An analogy with C pointers works fairly well here, as "x || y" in C
>is a short-circuiting operator that switches on "x != NULL" in the
>pointer case)
>Taking some key examples from the PEP:
>    data = data ?? []
>    headers = headers ?? {}
>    data ?= []
>    headers ?= {}
>When written using a doubled pipe instead:
>    data = data || []
>    headers = headers || {}
>    data ||= []
>    headers ||= {}
>Translations would be the same as proposed n PEP 505 (for simplicity,
>this shows evaluating the LHS multiple times, in practice that
>wouldn't happen):
>    data = data if data is not None else []
>    headers = headers if headers is not None else []
>    data = data if data is not None else []
>    headers = headers if headers is not None else []
>One additional wrinkle is that a single "|" would conflict with the
>bitwise-or notation in the case of None-aware index access, so the
>proposal for both that and attribute access would be to make the
>notation "!|", borrowing the logical negation "!" from "!=".
>In this approach, where "||" would be the new short-circuiting binary
>operator standing for "LHS if LHS is not None else RHS", in "!|" the
>logical negations cancel out to give "LHS if LHS is None else
>PEP 505 notation:
>    title?.upper()
>    person?['name']
>Using the "is not not None" pipe-based notation:
>    title!|.upper()
>    person!|['name']
>And the gist of the translation:
>    title if title is None else title.upper()
>    person if person is None else person['name']
>If this particular syntax were to be chosen, I also came up with the
>following possible mnemonics that may be useful as an explanatory
>    "||" is a barrier to prevent None passing through an expression
>    "!|" explicitly allows None to pass without error
>Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
>Python-ideas mailing list
>Python-ideas at python.org
>Code of Conduct: http://python.org/psf/codeofconduct/

Sent from my Nexus 5 with K-9 Mail. Please excuse my brevity.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150923/60c2efa8/attachment.html>

More information about the Python-ideas mailing list