Keeping Your Code Simple

Is there a shortcut to becoming a 10x developer? Is there some magical secret that — if you only knew it — would unlock a whole new world of software development mastery and productivity for you?

This is where the doubters are thinking “There are no shortcuts! Everybody needs to practice to get good!” And that’s true enough, but what are the experts of software productivity practicing, and is there one key thing that can make a huge difference?

Yes! There is!

But even if I share it with you — even if I give it away and spell it out for you in detail— it might take you 10 years to grow into and fully appreciate the simplicity of it.

At least, that’s what happened to me. It was spelled out to me in plain English by my high school programming teacher. I was walked step-by-step through the process of applying it using some example code. And it didn’t really sink in until 10 years later. But now, with the benefit of experience, it’s a lesson I appreciate profoundly, and even though I know it’s a lesson you can’t truly appreciate at first glance — I’m going to share it with you.

This secret is a key difference between average productivity and 10x productivity. Using the leverage that this secret provides, you can be orders of magnitude more efficient.

You can write code that is more reusable and less likely to break when new requirements are introduced and things change in the surrounding code.

The secret to being 10x more productive is to gain a mastery of abstraction. A lot of developers treat “abstraction” like it’s a dirty word. You’ll hear (otherwise good) advice like, “don’t abstract too early” or Zen of Python’s famous “explicit is better than implicit,” implying that concrete is better than abstract. And all of that is good advice — depending on context.

But modern apps use a huge amount of code. If you printed out the source code of modern top 10 applications, those stacks of paper would compete with the height of skyscrapers, and software costs a lot of money to maintain. The more code you create, the more it costs.

Abstraction is the Key to Simple Code

The right abstractions can make code more readable, adaptable, and maintainable by hiding details which are unimportant for the current context, and reducing the amount of code required to do the same work — often by orders of magnitude.

“Simplicity is about
subtracting the obvious
and adding the meaningful.”

~ John Maeda: The Laws of Simplicity

Abstraction is not a 1-way street. It’s really formed by two complementary concepts:

  • Generalization — Removing the repeated parts (the obvious) and hiding them behind an abstraction.
  • Specialization — Applying the abstraction for a particular use-case, adding just what needs to be different (the meaningful).

Consider the following code:

const doubleList = list => {
  const newList = [];
  for (var i = 0; i < list.length; i++) {
    newList[i] = list[i] * 2;
  }
  return newList;
};

There’s nothing inherently wrong with the code, but it contains a lot of details that may not be important for this particular application.

  • It includes details of the container/transport data structure being used (the array), meaning that it will only work with arrays. It contains a state shape dependency.
  • It includes the iteration logic, meaning that if you need other operations which also need to visit each element in the data structure, you’d need to repeat very similar iteration logic in that code, as well. It forces repetition which could violate DRY (Don’t Repeat Yourself).
  • It includes an explicit assignment, rather than declaratively describing the operation to be performed. It’s verbose.

None of that is necessary. All of it can be hidden behind an abstraction. In this case, an abstraction that is so universal, it has transformed the way modern applications are built and reduced the number of explicit for-loops we need to write.

“If you touch one thing with deep awareness, you touch everything.”

~ Thich Nhat Hanh

Using the map operation, we can reduce the code to a one-liner by removing the obvious (the parts we’re likely to repeat in similar code), and focusing on the meaningful (just the stuff that needs to be different for our use case:

const doubleList = list => list.map(x => x * 2);

Junior developers think they have to write a lot of code to produce a lot of value.

Senior developers understand the value of the code that nobody needed to write.

Imagine being the coder who popularized the use of the map operation in programming languages like JavaScript. Map abstracts away details such as the type of data you’re mapping over, the type of data structure containing the data, and the iteration logic required to enumerate each data node in the data structure. It’s improved the efficiency of every app I’ve built in the past decade.

Jeremy Ashkenas made several such operations popular in JavaScript, and paved the way for many of the great syntax shortcuts we take for granted now in JavaScript by pioneering their use in CoffeeScript. He made Underscore, which spawned Lodash (still the most popular functional programming utility belt in JavaScript), and Backbone, which popularized MVC architecture in JavaScript and set the stage for Angular and React.

John Resig made jQuery, which was so popular and influential, it formed the biggest collection of reusable, encapsulated JavaScript modules (jQuery plugins) until standard Node modules and ES6 modules appeared several years later. jQuery’s selector API was so influential it forms the basis of today’s DOM selection APIs. I still benefit on a nearly daily basis from jQuery’s selection API when I unit test React components.

The right abstractions are powerful levers that can impact productivity dramatically. Abstraction is not a dirty word. Modules, functions, variables, classes — all of these are forms of abstraction and the entire reason any of them exist is to make abstraction and composition of abstractions easier.

You can’t build complex software without abstractions. Even assembly language uses abstractions — names for instructions, variables for memory addresses, code points to jump to for subroutines (like function calls), etc. Modern software is a layer cake of useful abstractions, and those layers give you leverage.

“Give me a lever long enough and a fulcrum on which to place it, and I shall move the world.”

~ Archimedes

The key to simplicity: The secret we’re after — is how to reduce the mountain of code we’re producing — how to get a lot more done with a lot less. When you master that, you will be a 10x programmer. I guarantee it.

Source link

Most Popular