On 1 December 2017 at 04:49, Antoine Pitrou email@example.com wrote:
On Wed, 29 Nov 2017 18:14:36 +1000 Nick Coghlan firstname.lastname@example.org 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".
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.