Skip to content

On Inheritance

I recently had the chance to give my OOP-in-FP-in-Swift talk again in NSLondon, and was asked how to build inheritance in that object system. It’s a great question, I gave what I hope was a good answer, and it’s worth some more thought and a more coherent response.

Firstly, let’s look at the type signature for an object in this system:

typealias Object = (Selector) -> IMP

A Selector is the name of a method, and an IMP is a function1 implementing that method. But an Object is nothing more or less than a function that maps names of methods to implementations of methods. And that’s incredibly powerful, for two reasons.

Reason one: Inheritance is whatever you want it to be.

You are responsible for writing the code to look up methods, which means you get to choose how it works. If you don’t like inheritance at all, then you’re golden: each object knows its own methods and nothing else.

If you like Javascript or Self or Io, then if your object doesn’t have a method then it can send itself a proto message, and ask that object what method to use.

If you like Smalltalk or ObjC or Ruby, then you can create an object called a Class that creates objects that look up methods by asking the class what methods to use. If the class doesn’t know, then it can ask its superclass.

If you like multiple inheritance, then give an object a list of classes/prototypes instead of a single one.

If you’ve got some other idea, build it! Maybe you always thought classification should be based on higher-order logic; well here’s your chance.

(By the way, if you want to do this, you would be well-off defining a convention where methods all take a parameter that can be bound to the receiver: call it this or self for example. Then when you’re deep in inheritance-land, but you want to send a message to self, you still have a reference to it.)

Reason two: Inheritance is whatever you want it to be at each point.

A failing common to all of the object systems named above (as a reminder, that’s Javascript, Self, Io, Smalltalk, ObjC, Ruby) is that they force you to work with a single object paradigm. If these things naturally follow a singly-inherited classification scheme, but those things can be better described as deviations from a common prototype, well, sorry, but you’ve got to pick one and contort it to fit both situations.

If an object is any arbitrary code that finds a method, then you can build whichever model is most appropriate at the point of use. You can mix and match. The core philosophy at a code level is that objects are just loosely-coupled functions. From a conceptual level that’s incredibly powerful: such loose coupling means that you aren’t forced to make assumptions about how objects are constructed, or glued together. You just use them.

  1. actually a closure, which is even more useful, but that’s not important right now. 

Post a Comment

Your email is never published nor shared. Required fields are marked * Comments are moderated; please make sure that your post is civil and valuable before submitting it to improve the chance it will be accepted.