With the new variable annotation syntax, it is possible to implement a
useful "modifiers" library, all used as superclasses.

Possible modifiers:
  * Named / Struct: annotation-defined fields. No monkey patching.
  * Immutable / Const
  * Sealed / Final: unsubclassable class
  * Array: a mutable tuple. (No "+" or "*" operators)

There of course may be others. Subclasses of the modifiers get default
methods and behavior.
The modifiers can used in combinations. For example:

    class Command(Immutable, Named):
        cmd : str = "NOP"
        value : int = None

    load = Command(cmd="load", value=1000)  # no positional arguments

The syntax for Array is less pretty:

    class Command(Array):
        _0 : str = "NOP"
        _1 : int = None

    load = Command("load", 1000)  # no positional arguments

Many other combinations are useful too. "Sealed" is almost orthogonal to
the others,  Obviously, some combinations already exists:
  * (Immutable, Array) is similar to Tuple
  * NamedTuple is another name for (Immutable, Named, Array).
  * Enum should be on this list too

Some less promising modifiers:
  * Namespace / Static: uninstantiable class. A module.
  * Volatile, for externally facing classes. Hints the static checkers /
jitters that they should not assume they know the values.
 * Abstract

Alternatives and cons :
I suggest base classes instead of decorators since NamedTuple and tuple go
this way, and since it is static information. I am not sure which is better
though.
Metaclass parameters can be used (and actually used in my implementation,
and in NamedTuple's), but the syntax is uglier.
"array" is only for numeric values in Python, so this name is
problematic.So is struct.

I have a rough implementation for most of the above; much of it is not hard
in general, though some details are hard to get right.
---

Benefits of putting such a collection in stdlib (instead of as an external
package) include:
1. This information can be used by typecheckers, and also by users, to
reason about programs. If isinstance(x, ImmutableArray), then x is an
instantiation of ImmutableArray.
2. A conventional syntax and a single answer for "How do I make my class
immutable", "How do I make my class unsubclassable"
3. The syntax, especially for Struct as above, is pretty and clean. The
Array syntax is less so.
4. I think that the array implementation can use internal CPython details
to be implemented efficiently.

I am not sure that typing.modifiers is the right place, since these are not
exactly type hints; they generate methods, and are intended to be enforced
at runtime.

I think that even if this idea is not accepted, the general theme is
something that might be useful to keep in mind, stdlib might accumulate
such modifiers, and it will be nice to keep things uniform.

Opinions?

~Elazar
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to