Python's Path to Embracing Algebraic Data Types

Explore the evolution of Python with The Turing Taco Tales as we delve into its embrace of Algebraic Data Types. From static typing to pattern matching, discover Python's transformation in our latest article. Subscribe for more insights and join our programming journey!

Python's Path to Embracing Algebraic Data Types

Overview

Python began as a dynamically typed, object-oriented language, making discussing Algebraic Data Types (ADTs) nonsensical.

However, Python's gradual adoption of static typing and functional programming concepts brought Python closer to supporting ADTs, and that adoption is far enough along the road to merit a discussion.

Starting with Python 3.5, enhancements such as type hints and unpacking improvements laid the groundwork. Python 3.7 continued along the road by introducing data classes.

Python 3.10 took a big jump with enhancements like structural pattern matching, user-defined type guards, and improved union types syntax in Python 3.10. Even the latest version improves slightly with the introduction of type parameter syntax in Python 3.12.

Though type hints offer limited benefits, their inclusion marks a significant shift in Python's type system, making it a more versatile language capable of embracing functional programming paradigms and ADTs.

To maximize the benefits of adding type hints to our code, we can use mypy, an optional static type checker, and it potentiates these features by enforcing type hints at development time, maximizing the benefits of Types and ADTs in Python.


Embracing ADTs in Python 3.12: A Practical Example

From Python 3.12 onwards, the language offers more robust support for ADTs, mainly when used with mypy, the optional static type checker.

Consider the following example that demonstrates ADTs using Union Types and structural pattern matching:

Python 3.12

from typing import Union
from dataclasses import dataclass

@dataclass
class Circle:
    radius: float

@dataclass
class Rectangle:
    width: float
    height: float

@dataclass
class Triangle:
    base: float
    height: float

Shape = Circle | Rectangle | Triangle

def area(shape: Shape) -> float:
    match shape:
        case Circle(radius):
            return 3.14159 * radius ** 2
        case Rectangle(width, height):
            return width * height
        case Triangle(base, height):
            return 0.5 * base * height

# Example usage
circle = Circle(radius=5)
print("Area of circle:", area(circle))

rectangle = Rectangle(height=10, width=5)
print("Area of rectangle:", area(rectangle))

triangle = Triangle(base=10, height=5)
print("Area of triangle:", area(triangle))
        

The example above shows it is now fair to say Python supports ADTs. In line 5, we used Product Types called data classes in Python. In line 19th, we used Union Types and benefitted from the improved syntax using the or symbol |, and in line 22nd, we used structural pattern matching to define an operation on our Shape ADT.

This approach to defining and working with ADTs is both elegant and type-safe. When using mypy, it checks for completeness in handling all cases in a Union Type. If a case is missed, mypy flags an error, although the error message "error: Missing return statement" could be more precise. This feature ensures that each variant in the ADT is considered, enhancing the safety and robustness of your code.


Conclusion

As showcased through our example, Python's journey towards embracing Algebraic Data Types is a testament to its evolving and dynamic nature.

If you've found this article helpful, consider subscribing – every bit helps! We're grateful for every subscription, paid or free. Your support is what keeps us going.

Don't hesitate to comment if you're interested in a tutorial on installing Python 3.12 and mypy using pyenv.

We'll appreciate your feedback.


Addendum: A Special Note for Our Readers

I decided to delay the introduction of subscriptions, you can read the full story here.

In the meantime, I decided to accept donations.

If you can afford it, please consider donating:

Every donation helps me offset the running costs of the site and an unexpected tax bill. Any amount is greatly appreciated.

Also, if you are looking to buy some Swag, please visit I invite you to visit the TuringTacoTales Store on Redbubble.

Take a look, maybe you can find something you like: