[Python-ideas] PEP 505: None-aware operators

Steven D'Aprano steve at pearwood.info
Sun Jul 29 01:54:42 EDT 2018


On Sat, Jul 28, 2018 at 10:56:13PM -0500, Abe Dillon wrote:
> >
> > Python does not have memory locations.
> >
> 
> CPython does, form the documentation on the `id` function:

No, that is the same id() function as the id() provided by Jython, and 
IronPython, and Stackless. Like all Python implementations, it returns 
an opaque integer ID number.

That's why it is called "id" rather than "memory_location" or "address".


> *CPython implementation detail:* This is the address of the object in
> > memory.

An irrelevant implementation detail. You can't use the id() as a memory 
address, and even if you could, that wouldn't be portable Python code, 
it would be an implementation-dependent hack that is unsafe or 
unreliable to use.

Being an implementation detail, CPython is free to change it at any 
time, without warning or notice, even in a bug-fix release. If CPython 
ever gets a memory manager that can move objects around, as they can 
move in Jython and IronPython, CPython will also have to change id().

id() may, sometimes, *use* the memory address, but the semantics are 
not that of a memory address.


> I'm not sure what performance implications there would be for adding a
> __none_check__ or whatever method to None.

The point of testing for None is because you want None, and absolutely 
no other object but None. A __none_check__ method would allow other 
objects to lie about being None-like. The point of using "is" is to 
avoid that.

If you want any arbitrary object which happens to be a bit None-like, 
then call "x == None" and let x decide for itself. But be prepared to 
have experienced Python programmers correct your "mistake" unless you 
carefully document why you are doing this.


> Python is supposed to emphasize readability and learnability.

You're thinking of Scratch and other languages aimed at school kids.

Python emphasizes many things. Its not merely a kiddies' language, or a 
beginners' language, or an educational language. It is a language used 
by professionals, and frankly I'm getting sick to the back teeth of 
people saying "Mustn't do that useful thing because it will make Python 
harder for beginners to learn".

Fine. So it takes them an extra day to learn one more operator. Big 
deal. It is commonly believed to take ten years to master a field or 
language. Amortize that one day over ten years and its virtually 
nothing.


> To that end, expressions should strive to resemble natural language.

If you want a programming language that looks like natural language, you 
want something like Hypertalk:

  put the second word of field "Address" after line 3 of field "Record"

or Inform7. Or the granddaddy of "natural language" programming, COBOL.

Python is very little like natural language. Your earlier idea that 
attribute access spam.eggs is like natural language (in English) because 
its only a few characters different from "spam's eggs" really doesn't 
hold up. Apart from the word order, there's no similarity.


> Otherwise they should try to resemble common mathematical notation. Failing
> that, they should try to resemble common programming idioms.

Yes, common programming idioms like null-coalescing and null-aware 
operators, which are used by a good half dozen popular, modern 
languages.


> "?." doesn't resemble anything in natural language.

That's okay. Neither does spam.eggs, or spam[eggs], or anything to do 
with async, or function call notation func(a, b, c, keyword=d).


> It's not hard to check for None with a ternary statement. 

You're thinking in terms of trivial cases like 

    default if x is None else x

but replace x with a long, potentially expensive expression and 
you may think differently:

    default if spam(a, b, c, kw=d).eggs[cheese]() is None else spam(a, b c, kw=d).eggs[cheese]()

or a chain of tests:

    if spam(a, b, c, kw=d) is not None:
        if spam(a, b, c, kw=d).eggs is not None:
            if spam(a, b, c, kw=d).eggs[cheese] is not None:
                result = spam(a, b, kw=d).eggs[cheese]()


> Adding a '?'
> operator that goes at the end of an expression could do the same thing more
> elegantly 

I don't know that Python has any binary operators which are split 
into an infix part and a postfix part. I don't know any language with an 
operator like that. There is the ternary operator, of course, but this 
would be a binary operator.

So you're against:

    spam?.eggs?.cheese?.aardvark

but you prefer:

    spam.eggs?.cheese?.aardvark?

instead.



-- 
Steve


More information about the Python-ideas mailing list