Change the future

Friday 10:50 a.m.–11:20 a.m.

Composability Through Multiple Inheritance

Łukasz Langa

Audience level:
Intermediate
Category:
Best Practices/Patterns

Description

One of the turning points in history was when manufacturing embraced intermediate production. By creating simple components that can be integrated into complex products, manufacturers are able to build faster and cheaper, achieving better quality. In this tale of developer meets engineer,I describe how I'm using Python's inheritance model to bring this manufacturing reality to life in source code.

Abstract

Narrative

Programmers like vivid and clear statements. They work well as rules of thumb which can be used as justification of hard choices (especially bad ones but that's a whole different story!). One of those nuggets is: "Size is code's worst enemy". Very true. Unfortunately expressing any system of reasonable complexity requires vast amounts of code. What can be done to mitigate the risk of landing a codebase that is impossible to move forward?

A possible answer is: by using components, e.g. by dividing chunks of code into bits that can be freely composed together. In this talk, I discuss how multiple inheritance can be used as a composition tool which helps isolate unique bits of functionality. This leads to another useful principle of software developement: DRY (Don't Repeat Yourself). Done right, it can also be a way of creating truly reusable components.

The primary framework for real world examples will be Django, namely its ORM, forms and class-based views. However, the principles described are generic. Throughout the talk, I will mention details of implementing composable abstract models, form and view mixins. I'll explain how this approach creates readable and maintainable idioms along with pros and cons. I'll conclude by summarizing my experience trying to create a library of strictly reusable components.

Outline

Act I: Exposition

  1. What are composability and compositionality. Real life examples: Lego bricks, Unix pipes.
  2. Problem definition 1: Joe Armstrong's view on components -> it would be great to be able to treat them as black boxes. Example: grep.
  3. Problem definition 2: striving for Quality. Examples: Robert M. Pirsig, Jamie Zawinski.

Act II: Rising Action

  1. Don't use old-style classes.
  2. How does the MRO work.
  3. Cooperative inheritance without super().
  4. Cooperative inheritance with super().
  5. Mixins - keeping components orthogonal.

Interlude: problems with Django ORM inheritance.

  1. The Diamond Problem.
  2. Lack of polymorphism.
  3. Breaking Liskov substitution principle.

Act III: The Climax

  1. Real-world examples of reusable components for Django based on my lck.django library, e.g. abstract models handling time tracking, editor tracking, soft deletions, display counts, etc. etc. and how they can be freely composed together.