[Python-ideas] PEP 505 vs matrix multiplication

Nick Coghlan ncoghlan at gmail.com
Fri Dec 1 08:40:52 EST 2017


On 1 December 2017 at 04:49, Antoine Pitrou <solipsis at pitrou.net> wrote:
> On Wed, 29 Nov 2017 18:14:36 +1000
> Nick Coghlan <ncoghlan at gmail.com> wrote:
>>
>> As far as utility goes, I put it in a similar category to matrix
>> multiplication: if you don't need it, you don't need it, but when you
>> do need it, you need it a *lot*.
>
> As someone who appreciates both the matrix multiplication operator and
> "async/await", I really don't think PEP 505-style operators (regardless
> of their spellings) fall into the same conceptual bucket.
>
> There's no risk of matrix multiplication operators bleeding into
> non-domain specific code, and the readers of domain specific code
> already know about the matrix multiplication operator and what it
> does (or they should anyway, since it's so damn useful).  It's like
> "async/await": you won't find them in regular non-async code, so the
> mental burden only falls on specialists who write and read event-driven
> networking code (mostly, even though Guido would like to see parsers
> based on the idiom too :-)). Conversely, PEP 505-style operators may
> appear in everyday code regardless of their application domain or
> target.  This in turn increases the mental burden for *everyone*.

I genuinely don't think these kinds of operators are all that useful
outside the specific domain of working with semi-structured
hierarchical data stored in graph databases and document stores like
MongoDB, ElasticSearch, and PostgreSQL JSONB columns, or else piping
data between such stores and JSON consuming clients.

If there was a high change of their being broadly adopted outside
those domains, I don't think we'd be seeing the sharp division of
opinion that we see between folks that consider these operators to be
obviously useful, and those that are honestly befuddled as to why on
earth anyone would ever want them.

It's just that where matrix multiplication and async programming have
rich vocabularies and computer science foundations to draw on, the
None-aware and None-severing operators in different languages arise
more from the pragmatic hackery of working with semi-structured data
for tasks that are essentially a matter of reshaping blobs of JSON
from one system to feed into another (it's an imperative approach to
the kind of work that XSLT does for XML in a more declarative way).

The closest mathematical equivalent is a quiet NaN, but the PEP
already discusses some of the limitations of pursuing that approach
for algorithmic operations in Python:
https://www.python.org/dev/peps/pep-0505/#haskell-style-maybe

I think the PEP as currently written honestly goes too far into
symbolic magic, and hence doesn't give a reader enough hints to
plausibly guess what "?." means if they've never seen it before:

        return jsonify(
            first_seen=site.first_seen?.isoformat(),
            id=site.id,
            is_active=site.is_active,
            last_seen=site.last_seen?.isoformat(),
            url=site.url.rstrip('/')
        )

Thus the idea of possibly using "??" as a pronoun symbol (akin to "_"
at the interactive prompt) to allow both the condition and the RHS in
a conditional expression to refer to the LHS:

        return jsonify(
            first_seen = site.first_seen if ?? is None else ??.isoformat(),
            id=site.id,
            is_active = site.is_active,
            last_seen = site.last_seen if ?? is None else ??.isoformat(),
            url = site.url.rstrip('/')
        )

Here, even someone who's never seen "??" before has at least some
chance of guessing "OK, it looks like some kind of implicitly defined
variable reference. What might it be referring to? Well, the code
calls a method on it if it isn't None, so perhaps it means the LHS of
the conditional expression it appears in?".

And the transcription to English would probably use an actual pronoun:

    "We set first_seen to site.first_seen if that's None, otherwise we
set it to the result of site.first_seen's isoformat() method"

Further suggesting a potential name for the symbol: a "that"
reference. (Where precisely what "that" refers to will depend on where
the symbol appears, similar to regular pronoun usage in English).

It isn't the same way that languages that use "<cond> ? <then> :
<else>" for their conditional expression syntax do things, but
spelling conditional expressions as "<then> if <cond> else <else>" is
already pretty unique in its own right :)

"That" references could also be expanded to comprehensions and
generator expressions in a fairly useful way:

    [f(x) for x in iterable if ?? is not None]

Pronounced something like "f of x, if that's not None, for x in iterable".

Cheers,
Nick.

P.S. As previously noted, I don't think we should rush into anything
for 3.7 on this point, hence my deferral of all the related PEPs,
rather than requesting pronouncement. I do think the symbolic pronoun
idea is potentially worth exploring further for 3.8 though.

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


More information about the Python-ideas mailing list