PEP 622: Added rejected ideas section comparing with traditional OOP (#1504)

Co-authored-by: Brandt Bucher <brandtbucher@gmail.com>
This commit is contained in:
Talin 2020-07-07 19:35:05 -07:00 committed by GitHub
parent 26ac4b3d3e
commit 382f0dfc7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 60 additions and 11 deletions

View File

@ -1315,6 +1315,55 @@ above illustrate this comparison well enough. For more real code examples
and their translations see Ref. [7]_.
Don't do this, use existing method dispatching mechanisms
---------------------------------------------------------
We recognize that some of the use cases for the ``match`` statement overlap
with what can be done with traditional object-oriented programming (OOP) design
techniques using class inheritance. The ability to choose alternate
behaviors based on testing the runtime type of a match subject might
even seem heretical to strict OOP purists.
However, Python has always been a language that embraces a variety of
programming styles and paradigms. Classic Python design idioms such as
"duck"-typing go beyond the traditional OOP model.
We believe that there are important use cases where the use of ``match`` results
in a cleaner and more maintainable architecture. These use cases tend to
be characterized by a number of features:
* Algorithms which cut across traditional lines of data encapsulation. If an
algorithm is processing heterogenous elements of different types (such as
evaluating or transforming an abstract syntax tree, or doing algebraic
manipulation of mathematical symbols), forcing the user to implement
the algorithm as individual methods on each element type results in
logic that is smeared across the entire codebase instead of being neatly
localized in once place.
* Program architectures where the set of possible data types is relatively
stable, but there is an ever-expanding set of operations to be performed
on those data types. Doing this in a strict OOP fashion requires constantly
adding new methods to both the base class and subclasses to support the new
methods, "polluting" the base class with lots of very specialized method
definitions, and causing widespread disruption and churn in the code. By
contrast, in a ``match``-based dispatch, adding a new behavior merely
involves writing a new ``match`` statement.
* OOP also does not handle dispatching based on the *shape* of an object, such
as the length of a tuple, or the presence of an attribute -- instead any such
dispatching decision must be encoded into the object's type. Shape-based
dispatching is particularly interesting when it comes to handling "duck"-typed
objects.
Where OOP is clearly superior is in the opposite case: where the set of possible
operations is relatively stable and well-defined, but there is an ever-growing
set of data types to operate on. A classic example of this is UI widget toolkits,
where there is a fixed set of interaction types (repaint, mouse click, keypress,
and so on), but the set of widget types is constantly expanding as developers
invent new and creative user interaction styles. Adding a new kind of widget
is a simple matter of writing a new subclass, whereas with a match-based approach
you end up having to add a new case clause to many widespread match statements.
We therefore don't recommend using ``match`` in such a situation.
Allow more flexible assignment targets instead
----------------------------------------------