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

Nick Coghlan ncoghlan at gmail.com
Wed Sep 23 11:00:41 CEST 2015


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"
operations:

    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
LHS<OP>".

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
tool:

    "||" is a barrier to prevent None passing through an expression
    "!|" explicitly allows None to pass without error

Regards,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-ideas mailing list