the/experts. Blog

Cover image for Simple, Simpler, ... Complex?
Maik Kingma
Maik Kingma

Posted on • Updated on

Simple, Simpler, ... Complex?

How making things simpler can result in complex things.


I recently attended the biggest Java conference in the Netherlands, J-Fall. Next to meeting so many colleagues and friends from the industry, there were many inspiring keynote talks to attend. Two of them in particular sparked a thought in me and led me to write this blog post.

It is always a huge pleasure to attend one of Venkat Subramaniam’s talks, let alone two of them. At J-Fall 2022 he kicked off the conference with his keynote ‘The Art of Simplicity ‘, directly followed by his conference talk on ‘Design Patterns in the Light of Lambda Expressions’. If you were there, you know just how inspirational he is. However, if you were not, you can watch other versions of the talks here:

The Art of Simplicity by Venkat Subramaniam
and
Design Patterns in the Light of Lambda Expressions by Venkat Subramaniam

In his talk ‘The Art of Simplicity’, Venkat Subramaniam conveys the idea that humans tend to make things too complicated, and with good reason. As he puts it, imagine yourself in a situation where you have written a nice piece of code and somebody comes along and says: ‘Oh yeah, that looks simple!’. Most people would probably feel kind of let down. Whereas, if that same person comes along and says: ‘Wow, let me have a look, I am trying to understand what this code does!’ we feel good. Actually, we built something so complex, everybody except us, will have a hard time understanding it. And we feel exceptional because of it.

“Life is really simple, but we insist on making it complicated” - Confucius

In my opinion, we are driven by one of the most basic human needs: the need for appreciation. And in a misled attempt to gain such appreciation by others, we add complexity to what we create. Unfortunately, most of the world around us reacts positively to that unnecessary complexity. And as a result, our craving for appreciation is temporarily satisfied. For a moment, we do feel exceptional.

“Simplicity is the ultimate sophistication” - Leonardo da Vinci

Contrary to popular belief, it actually takes genius to make things simpler. But are they then actually simpler or will things only be less complex? Firstly, let’s focus a bit more on simplicity and what simple really means. According to Venkat Subramaniam ‘simple’ can be boiled down to five key aspects:

  • Simple keeps you focused
  • Simple fails less
  • Simple is elegant
  • Simple has less moving parts
  • Simple is not over-engineered

He underlines this by showcasing a most simple example that almost all people can relate to: a Google search. This is what the Google landing page looks like:

Google search landing page

Let’s check if it ticks the boxes.

With nothing on there but a logo, the search bar, and two buttons, it definitely keeps you focused on what you are trying to achieve: a search. How often do you think the HTML template needed changing in the past few years? Probably not that many times. Hence, it's less prone to errors and failure.
For me, less is more. This design appeals to my eyes, it is clean and elegant (hence simple).

So we ticked all the boxes and Google delivered a great example of what simplicity means. And as Venkat Subramaniam stated so nicely at J-Fall: It probably took the developer a lot of guts to propose this HTML template as the landing page for the biggest search engine in the world. Managers might have asked him what he had done with the rest of his days, and if they still needed to pay him for the 341 lines of code.

Since you are probably wondering, what an example could be that does not tick the boxes, here is the yahoo.com landing page.

Yahoo! search landing page

Same as Google, Yahoo! aspired to be the biggest search engine out there, yet somehow they cannot catch up to Google. Looking at it from a simplicity angle, I might actually forget what I wanted to search for because I now want to read the latest and greatest of what happened in the world. I also know that I will need an umbrella when I leave my house in a few days.
Put simply, I got distracted, the page does not look simple (although that might be subjective) and it is probably more prone to erroneous behaviour (more components that can fail).

On a side note, the developers of the Yahoo! page probably needed a lot more code than 341 lines to deliver this. But is it better? More valuable? And does it support me in the best way possible to achieve what I set out to do? This is why people should not get paid for how long they need to complete a task or how much complexity they can deliver while doing so. Especially in my area of expertise (IT) people should get paid to get the job done efficiently and in a simple way, with as little complexity added as possible. And that takes courage (and knowledge), as Einstein said. Because, after all, we might cross paths with those who see more value in complexity than in simplicity. Facing their judgement and defending the value of your simple solution will require just that: Courage and knowledge.

“Any intelligent fool can make things [...] more complex [...]. It takes a touch of genius - and a lot of courage - to move in the opposite direction.” - Albert Einstein

Simplicity is also deeply linked with the knowledge that we have. Judging if something is simple is often subjective and influenced by what we know and what we are familiar with. To somebody with no experience in the coding world, even the most simple piece of code might look complex. Whereas, If you are a developer who has never worked with Java’s stream API, using the imperative coding style will be the ‘simpler’ solution for you. Though, simpler might not be the right word here. That developer is simply unfamiliar with the declarative style. As Venkat Subramaniam correctly assesses, we should not confuse familiar with simple : ‘A lot of us are familiar with imperative style, but declarative is simpler’.

Let’s illustrate this with an example:

import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        var names  = List.of("Josh", "Layla", "Emma", "Senna", "Tim", "Theo");
        System.out.println("Let's print all names with even # of characters, separated by Comma");
        System.out.println("Imperative: ");
        printEvenNamesImperative(names); // prints Josh, Emma, Theo
        System.out.println("Declarative: ");
        printEvenNamesDeclarative(names); // prints Josh, Emma, Theo
    }

    // Imperative
    public static void printEvenNamesImperative(List<String> names) {
        for (int i = 0; i < names.size(); i++) {
            String current = names.get(i);
            if(current.length() % 2 == 0) {
                if(i < names.size()-1) {
                    current += ", ";  // (2)
                }
                System.out.print(current);
            }
        }
        System.out.println();
    }

    // Declarative
    public static void printEvenNamesDeclarative(List<String> names) {
        System.out.print(names.stream()
                .filter(name -> name.length() % 2 == 0)
                .collect(Collectors.joining(", ")));  // (2)
    }
}
Enter fullscreen mode Exit fullscreen mode

Functionally speaking, both functions achieve the same thing, namely the printing of Josh, Emma, Theo. Judging them based on their implementation, though, we immediately see that the imperative style adds way more complexity than the declarative one does. The Java stream API enables us to write simple and easy to read code where it immediately becomes clear what the code is supposed to do. Especially, we see a lot less complexity when it comes to iterating over the list entries and the appending of a ‘, ’ between two adjacent names (2).
However, the stream API is something that was introduced in Java 8. Before that, we would not have been in the position to deem the imperative implementation as something familiar but not simple (or even complex).

“Simple lies in the eye of the beholder” - Anonymous

All of the above eventually leads me to the assumption that simplicity is a temporary judgement. I can build something simple, based on what I know now. When I learn something new in the future, I can take that knowledge and make what I previously created even simpler. And then I learn this new technology, some new way of doing things and my initial simple, then enhanced simpler solution suddenly becomes complex, even to me. Thus, we can add one more assumption about simplicity to the 5 original ones from above:

Simple can become complex over time

For me this underlines once more the importance of continuous improvement, not only applied to our code base but also to our knowledge base. That is, only by constantly evolving our knowledge we can try to keep up with the rapidly advancing technology and put ourselves in a position where we are capable of recognizing something simple, something complex, or something simple that became complex through newly gained knowledge.

Last but not least, you are probably wondering about the second talk that I referenced in the beginning, namely, ‘Design Patterns in the Light of Lambda Expressions’. Well, I would encourage you to watch it! Especially if you are unfamiliar with lambdas, functional programming and patterns such as the iterator pattern, the decorator pattern and others. Venkat Subramaniam shows in an outstanding way how to enhance your functional programming skills. As developers, we constantly need to challenge ourselves to become more knowledgeable and put ourselves in a position where we can recognize complexity and make it simple again. Hence, my challenge to you to take a first step on the journey back and forth between simple, simpler and complex. Continuously extend your knowledge and start recognizing what is simple, and what is complex.

Discussion (0)