Switching from B:: to BETA examples in my roles talk
In my my roles talk I have a long section on the B:: modules but that is so confusing to folks (as one might expect from multiple inheritance (MI) and B:: modules) that I decided to rip it out. I've replaced it with an example from the BETA programming language (all CAPS in BETA is from them, not me).
While this example is fascinating, I realised that I no longer had a damning indictment of multiple inheritance. I'm hoping that I won't need it and people will follow what's going on, but I'm now unsure and I have less time for revising this talk. However, in the process of thinking and researching about this, I discovered something interesting.
In the BETA programming FAQ, there's a very telling explanation of why they do not (yet) support multiple inheritance (emphasis mine, but all of this is important):
When BETA was designed we did not think that the concept of multiple inheritance was ready for being incorporated in the language. One of the main design goals for BETA was that it should be good for modelling. Most usages of MI seemed to be for pure code reuse, i.e. a new class may be defined by inheriting from a number of classes and then redefining the parts that should differ. Often this is done without there being any conceptual relation between the new class and the ones it inherits from. We did not like that way of using inheritance.
As I dug down further, every example of multiple inheritance in Perl I could find was about code reuse, not about intrinsic class responsibilities.
- We use MI for code reuse
- We know that single inheritance is less problematic that multiple inheritance.¹
What's wrong with simply using single inheritance for code reuse? It turns out that a lot of single inheritance code I find in Perl is also for code reuse and not for more specific responsibilities. Given that people have been arguing about the correct use of inheritance for over 4 decades, it's not an entirely indefensible position. After all, your Person class inherits from DBI::Class::Core, right? It's easy to argue that "name" and "birthdate" are responsibilities that the Person class should have. Arguing "persist to a database" isn't simply code reuse is a bit more difficult.
It's also interesting to note that when I read books about OO design, they have various strategies such as UML diagrams or CRC cards to figure out where various responsibilities lie, but invariably there's a "you'll get it wrong the first time" caveat. Once we see how to separate our responsibility and code reuse, things get a lot simpler. In the future, I expect OO design books to be much simpler with roles. We'll just need to figure out cleaner ways of explaining them.
1. The problems of multiple inheritance can be viewed as a superset of the problems with single inheritance.