[Python-ideas] An Everything singleton

Andrew Barnert abarnert at yahoo.com
Tue Feb 18 22:45:45 CET 2014


From: Serhiy Storchaka <storchaka at gmail.com>

Sent: Tuesday, February 18, 2014 11:07 AM


>T his crazy idea is inspired by a discussing in Python-Dev which should be here.
> 
> Currently we have a None singleton which representing nothing and raises an 
> exception in almost all operations (except equality, etc). What about 
> introducing its antonym, an Everything singleton (the name is discussable), 
> which newer raises an exception in any operation, but returns consistent value?
> 
>>>>  Everything + 2
> 2
>>>>  Everything < 3
> True
>>>>  Everything * 'foo'
> 'foo'


What about these:

    >>> Everything + None
    >>> 1 if Everything else 0
    >>> int(Everything)
    >>> iter(Everything)
    >>> next(Everything)
    >>> Everything(23, kw=42)

    >>> Everything[-1, 1:3, ...]
    >>> range(Everything)
    >>> spam(1, Everything, 2)
    >>> eggs[Everything:-1]

None acts a lot like a singleton value of an ultimate superclass, if the language had such a thing. In fact, it acts almost exactly like, e.g., Scala's null, where null is a singleton instance of the ultimate superclass Null (well, it's really a penultimate superclass; there's Nothing, with _no_ instances, above it… but that isn't relevant here).

So Everything should act like a singleton value of an ultimate subclass, right? But Python has an ultimate subclass, object, and it already works almost exactly like Scala's equivalent, Any. You can create lots of object instances, and it can make good sense to do so (e.g., as separate sentinels for separate functions at the same scope). These instances support only a bare minimum set of operations (equality testing, type testing, hashing, string-representing, and introspection). In Scala, Any is also useful as a declared type for variables, as a way to wedge duck typing into static typing (a function can take an Any parameter, a collection can be parameterized on Any element type, etc., in which case they effectively act like Python functions and collections), and there are a few places in or near Python (e.g., parameter attributes used for type annotation, Cython variable types, the PyObject* type and "o"-related arg types in the C API, etc.) where
 it's used for the same thing.

So, Everything clearly isn't the opposite of None in that sense. So… what type _is_ it?

Maybe Objective C's nil is a better model. It's a legal value of all types (even those that aren't derived from NSObject or any alternate real class root), and you can call any method on it and it will return nil. But you still can't pass it as an argument to any arbitrary function or operator and expect to get back anything consistent (and, to the extent that you _do_ expect something consistent, it's nil, not some other value from the expression). And the same is true with SQL NULL, IEEE NaN, and every other similar value I can think of: they all avoid exceptions by "infecting" every expression as much as possible, not as little as possible. 

For a type like that, Everything is easier, but there are still some problems:

    >>> Everything + 2
    Everything
    >>> Everything < 3
    ??? (could be Everything, but you still have to decide whether that's truthy…)
    >>> Everything * 'foo'
    Everything
    >>> Everything + None

    Everything
    >>> 1 if Everything else 0
    1 # assuming Everything is truthy, as above
    >>> int(Everything)
    Everything # fine, but what about Everything.__index__()?
    >>> iter(Everything)
    Everything?
    >>> next(Everything)
    Everything?
    >>> Everything(23, kw=42)

    Everything?
    >>> Everything[-1, 1:3, ...]
    Everything?
    >>> range(Everything)
    ???
    >>> spam(1, Everything, 2)
    ??? # often Everything, but no guarantee
    >>> eggs[Everything:-1]
    ???

But anyway, even if it's easier to define, it's not what you wanted…



More information about the Python-ideas mailing list