1. 9

    I don’t think the “X is terrible” rhetorical device serves to really tell us anything about X. I get the idea of a flashy header, it’ll get more reads, generate more discussion, etc.

    I think it’s more useful to focus on the tradeoffs inherent in using a tool.

    Inheritance gives us a way to treat objects polymorphically and enforces a heirarchy of specialization on those objects.

    The tradeoffs for this behaviour are:

    • high cost of maintenance for any children of a given class (in this case the same as any breaking change to an interface)
    • any further extension relies on changing parents or using interfaces and composition.

    • by contrast interfaces and composition can achieve the same behaviour without relying on some external pattern.

    That doesn’t make it a useless pattern, it just makes it useful in a few limited cases.

    • With exceptions it allows us to create ‘families’ of exceptions which are useful for debugging. This would be pretty tricky to pull off with composition or interfaces since the programmer would have to implicitly encode that heirarchy and ensure they’ve extended correctly.

    • In ruby it (for better or for worse) allows us to add behaviours to all objects or all objects of a given class.

    It would be pretty difficult to implement an OO language without single inheritance, and for code that, once stable, is rarely modified the maintenance costs can be amortized over millions of person-hours.

    No tool or technique is universally good, but I think avoiding a tool at all costs also prevents us from learning its strengths and weaknesses.

    1. 7

      I’d argue that Go is a successful OO (or maybe OO-lite) language without inheritance. It has struct embedding, which forwards method calls from a type to one of its embedded subtypes, but no concept of a abstract base class and super keyword.

      1. 2

        Regarding inheritance in OO, it is good to note that there is also prototypical inheritance, which, oddly enough, is the base model for JavaScript. Io is a notable modern language built on prototypical inheritance, Self is probably the oldest/most interesting one. Prototypical inheritance is quite interesting because it is quite simple and versatile, and you can build single inheritance on top of it.

        1. 2

          I think rather than talking about if X is terrible or not, the discussion should be around if the feature is important enough to be included as a concrete concept in a language. For example, you can implement inheritance yourself with a record and some functions, so is it important enough to have a language construct that, more or less, creates that struct for you.

          1. 1

            I’m a big fan of having less, for most languages under debate, that ship has long since sailed though.

            1. 3

              Sure, but these discussions are never about if it will be removed from a language of or if developers will stop using it, it’s just about thinking about the value of things. Every once in a while a language like Go gets momentum and people have a chance to reset things a little bit (regardless of if one likes Go or not. it’s a popular language that dials back some existing popular features.