Working Memory & Programming Paradigms

Cognitive psychologist George Miller argued that you can only have 7 (+2) things in your working memory. Obviously the exact number varies by person, type of information, day etc.., regardless of the actual number, working memory is a significant bottleneck to a programmer's productivity. This really sucks! Nobody likes to think about their own shortcomings, but ignoring this fact isn’t helpful. Rather than ignore it, let's acknowledge it as a bottleneck for complex thought work.

As far as I can tell there is no way around this limit, however there are things you can do to make yourself more productive when you consider this limitation. One of those things is relying on Google less and memorizing more, which I’ve talked about before. But what else can you do to be more productive, given your the working memory constraints?

Value Simplicity

I remember when I was learning programming, one of my professors tried to drive home the concepts of simplicity, while at the same time teaching me Java. Needless to say I struggled to embrace simplicity when the world around me was complex. Java and all object oriented languages are inherently complex. Many would say Object oriented languages hide complexity, but in practice that doesn’t really hold true.

Complexity in Object Oriented Programming

On the surface objects seem simple, they represent things like people, items and orders, however appearances can be deceiving. Objects are kind of like Icebergs, what you see seems far smaller than what’s actually there.

Ok, so what’s the problem with objects?

They are by definition complex because they combine data and behaviour, resulting in something that is stateful.

The definition of simple is: things that are easily understood or done ; composed of a single element.

When you interact with an object, you need to know the current state of the object to accurately predict the outcome of interacting with the object. When you use an object, thinking about that object may fully consume and overload your working memory. You’ve got to know the answer to questions like:

  • What’s the purpose of this object
  • What can I do with this object
  • How is this different the object x
  • Where was this object created
  • Where did it get used before this point in the code
  • What’s the current state of the object
  • What’s going to happen when I call this method, does the state get modified, do I get a value back
  • Will I always get the same result when I call this method
  • ...

Now honestly you probably don’t always think about these questions, which likely works most of the time, but it’s kind of dangerous and eventually you’ll hit bugs where you have to think about these types of questions. And when you fix the bug, you’ve got to think about how your fix may affect other things and potentially cause regressions. Objects are a complicated onion that promise far more than they deliver.

Ok so what's a better alternative?

The simpler option is to separate the values from the behaviours and eliminate state as much as possible. So instead of encapsulating your data in an object, just use simple values like Integers, Strings, records, hashes and lists. Then when you need some sort of behaviour, just use pure functions that receive a value and return a value and cause no side effects. By doing this you’ve eliminated the Iceberg, now what you see is what you get: Values and Functions. Additionally using simple values and functions provides guarantees that object oriented approaches can’t offer, the guarantee that a particular input value will always return the same output value. Now all of a sudden, the only thing you need to store in working memory is data and functions.

Really functional programming?

For the longest time, I pretty much ignored functional programming. It seemed like an academic thing, that the industry didn’t embrace, so why should I. Turns out the academics were really onto something, but they generally did a horrible job of explaining the value and persuading developers to use it. Academics used a bunch of mathematical terms that turned many of us away, they focused on theory over practical use. Historically most functional programming languages have a steep learning curve that scares away most beginners, but fortunately there are better options now.

Learning Functional Programming

Many languages support functional programming concepts, so for example you can program using a functional style in JavaScript. If you must program in JavaScript, adopting a functional style is a great idea, however to be clear JavaScript isn’t a functional programming language.

So what is a functional programming language?

It’s a language that enforce functional concepts, so you have no choice but functional programming. Theoretically you could learn and use functional programming concepts in an imperative language that supports functional style, like JavaScript, but I suspect most of you will have limited success with this approach as most of us tend to gravitate back to what we know. To truly learn Functional Programming, I’d suggest learning a functional programming language. This will force you learn all the important concepts, ensuring don’t take any shortcuts or lean on your existing imperative language knowledge.

What language should you learn?

I believe the best way to try functional programming today is Elm. You’ll learn most of the valuable concepts, without being bombarded with scary terminology. You’ll be productive in days, instead of years. In the end, I bet you’ll learn more from Elm than you would from learning any other imperative language. I like to think of Elm as functional languages the good parts.