NVNH.io Logo

Sep 4, 2022

Composing Software by Eric Elliot, what you need to know

Functional programming (FP) is a big deal in the Javascript community. It’s one of the fundamentals of building good software and great to learn if you want to grow as a developer.

FP has its roots in math academia, so a lot of the learning material is theoretical, making it hard to wrap your head around. It’s not always easy to see how you can apply it in your day job. The more practical information is scattered and often hidden in documentation for specific libraries.

I don’t know of any course or book that’s the reference on Functional Programming in Javascript. I have recommended Composing Software by Eric Elliott, but apparently some people don’t like that.

I do agree with some of the criticism, but it sounds like the whole book is rubbish and that’s not true at all. You can still learn a lot from it: most of the advice is good, it doesn’t go too heavy on the theory and the examples are practical.

There are a few things you should know: two OOP principles that come up in the book, object composition and the open-closed principle, are not used correctly. The book describes a forgotten history of OOP before getting into these things, but that’s not a good reason to confuse readers by redefining well-known OOP principles. Let’s see what’s going on here.

The wrong definition of Object composition

Skip the chapter on object composition. It explains that there are 3 types of object composition, but I’m not sure where these are coming from. It’s confusing.

“What is object composition” starts with a quote from Wikipedia, but it comes from the Composite data type page and not Object composition.

Then 3 types of object composition are described:

  • Aggregation: I don’t know where this definition of aggregation comes from, but in the classic GoF book and in UML, aggregation has a different meaning.
  • Concatenation comes back later in the book in the chapter about functional mixins. We will come back to this in the next section.
  • Delegation uses a form of object composition, so I can kind of see how it relates, but it’s closer to class inheritance than object composition. It’s not very relevant to what you should know about object composition and why you should favor it over class inheritance.

Mixins are not “object composition” in “favor object composition over class inheritance”

In the chapter “Functional Mixins” the confusion about object composition continues:

Mixins are a form of object composition

And then a few paragraphs further:

it is the most common form of inheritance in JavaScript

So… are mixins composition or inheritance?

Technically speaking, describing mixins as “object composition” is not wrong if you only consider the meaning of the words in English: you’re composing objects together to form a new object. But when we talk about object composition in OOP, this is not what we mean. Functional mixins are a form of multiple inheritance, not object composition.

It’s not a bad technique, it’s useful to know it and use it. Just remember that you’re doing multiple inheritance. The book seems to suggest that you’re applying “favor object composition over class inheritance”, but this is not true. In fact, the “Caveats” section has this warning:

Like class inheritance, functional mixins can cause problems of their own. In fact, it’s possible to faithfully reproduce all of the features and problems of class inheritance using functional mixins.

Composition is not necessarily harder with classes

In “Why composition is harder with classes” the book tries to make the point that composition is harder with classes because mixins are harder with classes. Since mixins are not object composition, this is not correct.

What you should remember from this chapter is:

  • A factory function is more flexible than new or class.
  • Changing from new or class to a factory function could be a breaking change.

A clumsy reference to the open-closed principle

Further in this chapter, there is a section called “Code that Requires new Violates the Open/Closed Principle”. It starts like this:

Our APIs should be open to extension, but closed to breaking changes.

This is good advice and the open-closed principle has a similar high-level goal, but it’s not what the open-closed principle means.

The open-closed principle generally means what Wikipedia calls the polymorphic open–closed principle. We would use interfaces rather than abstract base classes these days, but Robert C. Martin’s article is in C++ and from 1996. The concept of interfaces didn’t exist in the language, abstract base classes were the closest thing.

That’s not acceptable, aren’t there any other resources to learn from?

Specifically for Javascript there are some alternatives:

Personally I learned functional programming from an online course on Coursera: Functional Programming Principles in Scala. It’s a lot of work to learn a new language and translate what you learned to Javascript just to get into functional programming. I didn’t learn Scala just to get into functional programming. But if you’re serious, and you’re up for a challenge, feel free to learn Scala. Or go find the definitive learning material for purely functional languages like Haskell or Lisp. It’s not the most efficient way, but you will learn a lot, I promise!

Want to learn more? Sign up for the newsletter!

Stop trying to keep up with every new technology to stay relevant! Technologies come and go, but the fundamentals of building good software don't.

I will occasionally send you an e-mail about the fundamentals of building good software. About the things full stack engineers generally struggle with and solutions that stand the test of time. The stuff that stays relevant for the rest of your career!

Examples of topics:

  • Building high-quality software (and why)
  • Dealing with changing requirements
  • Keeping the software in a good place while business wants features ASAP
  • Dealing with legacy code
  • etc...