Clean Code

Making a Name for Someone Else

and standing out as a software engineer

Stephen White
The Startup

--

image courtesy of Jozef Micic

There are only two hard things in Computer Science: cache invalidation and naming things.

— Phil Karlton

Why are good names important?

Good names convey intent. Which in turn gives your peers (and your future self!) more insight into your design. Furthermore, it can describe what something is and/or what it does,

First, let’s go over the who, when, where, why, what, and how (5W1H) of your code….

Who, When, and Where

Who, when, and where can be derived from facts pertaining to your codebase. Who is calling your code and where is it being called from? A user on a web browser, code running on a server, ComponentA calling a function provided by ComponentB, etc. When is your code being called? After a user logs in, before a websocket message is sent, etc. Familiarity with your system’s tech stack and some digging throughout the code can provide you answers to the who, when, and where.

Why, What, and How

This is where clean code and solid naming conventions show their true value. When contributing to the codebase, one of your goals should be to make the why, what, and how as clear as possible for the next developer that may see your code. Let’s go through each of these, 1 by 1.

Why

As far as the code is concerned the best place to explain why is through comments.

The JSDoc comment in the example above gives developers insight into why this function exists and implies that any other concerns should be kept separate—and likely put into a different function. Comments should rarely explain anything else. In some cases however, it can be helpful to write a few words about what a function does if it will be used in many places throughout the codebase and/or if it’s unavoidably complex.

How

How is were we get to the good stuff (hopefully it’s the good stuff 😬)—code. Reading the code should give developers a clear idea of how it works. This is where should take your time to figure out the best way to both solve a problem and give others a window into your approach. In the “sparkling water” example below, you’ll see that the how pertains to the logic we use to filter the drinks array.

What

The premise for this post is centered around the what and how it relates to naming. In code, you’re mainly concerned with naming variables, function/methods, and data structures. In JavaScript, this comes in the form of booleans, strings, objects (or classes), arrays, numbers, and functions. Beyond code, there’s also files, directories, packages, jars, etc. There are a lot of names to think about!

Variable Naming

Occasionally you’ll run across code like the above. It’s doing something, then storing the result. But what is the result? The variable name arr doesn’t really give us any clues. You’re forced to dig through the code to find out. Which isn’t the worst case scenario, but if you were just skimming past this code in search of a bug, it’d be nice to get the gist by just glancing at it. Luckily the above is fairly simple and easy to read. But I’m sure we can all imagine or remember a more complex example that could’ve benefited from a well-named variable to store the result.

Instead of arr, what could the name be?

  • drinks— Definitely more specific than arr. And in small functions, this might be sufficient. But we can improve.
  • sparklingWaters — Even more specific. It’s not just an array of various drinks, but sparkling waters specifically.
  • sparklingWaterList — This is also good. However, changing the data structure (i.e. to an object/map) would require updating the name as well. No biggie either way, but something to keep in mind.
  • lemonSparklingWaters— Even more specific. This tells us sparkling waters in this array are lemon flavored.
  • emptyLemonSparklingWaters ✅— The most specific name so far. It’s a bit wordy. But that not necessarily a bad thing. We’ll see why later.

Now I don’t want to be too prescriptive and say that emptyLemonSparklingWaters is the optimal name, but in this scenario, it’s definitely what I would go with.

I’ll let your imagination run wild as to why someone would need to collect empty lemon flavored sparkling waters in the first place. I’m not even sure why I went with this example… there just happens to be one right next to me… and it was delicious 😋.

Function Naming

Imagine you encounter the following:

even Superman is confused 😔

Not horrible, but we can improve this a ton by using some better names—most notably the function thats being passed to data.filter().

We don’t have a clue about what data actually is until we see some of its properties later on. Further, we don’t know why we’re filtering by those specific properties and values in the first place.

Caveat: Sometimes you’ll see the above within the context of a well-named function. But writing meaningful names isn’t exclusive to a certain level or section of your codebase. It’s important all the way throughout.

Let’s refactor a bit and add some more thoughtful names:

With the above modifications, we can clearly see what the intent behind the code. Although it’s more verbose, it’s also more intuitive. After only skimming, we can come up with a brief synopsis of why it exists and what it does: get a list of currently enrolled students that are eligible for grants.

Key changes:

  1. The function getData() turned into getCurrentlyEnrolledStudents(), hinting at what we can expect it to return.
  2. The variable data turned into students. We could’ve kept data as the name since we see it’s initialized with the return value of getCurrentlyEnrolledStudents(). But to keep things clear and avoid any mental mapping to the actual value of data, we renamed it to students.
  3. The anonymous function used to filter the array of students was split out and given the name isEligibleForGrant. At a high-level, we now know what kind of filtering is going on without having to dig in to each conditional statement individually.
  4. In opposition to reducing lines of code, we opted to name the conditional statements used for filtering (using the is or has boolean prefix convention). isJunior explains the reasoning by checking if the student’s credits are ≥ 60. And hasExcellentPerformance explains why we’re checking to see if the student’s overallGpa is ≥ 3.5 and recentGpa is ≥ 3.5.
  5. I missed a spot 😉. See if there’s something else that could have been given a name (answer at the end).

Don’t be afraid to be verbose.

The benefit of being a little verbose is that we don’t even need to look through all of logic to get the gist of what values we end up with. By adding a little more detail to your variable and function names, you speed up the amount of time it takes for someone to understand your code. It also helps out in debugging. For example, if someone were to inspect the value of emptyLemonSparklingWaters at runtime and discover both empty lemon and tangerine flavored sparkling waters, they can be certain that something went wrong. Either the variable name is incorrect or the logic is incorrect.

Also, check this out:

AbstractInterruptibleBatchPreparedStatementSetter

It’s an almost humorously long class name from Spring Framework. Some may say the above is too long. However, there are others that may say they at least have a good idea of what this class is used for (without needing to look at the code or docs).

These are 2 quotes that come to mind when I think about reducing lines of code:

Less is more.

— Ludwig Mies van der Rohe

What’s understood doesn’t need to be explained.

— Anonymous

However, as you’ll see below, less code isn’t always better. More information can often provide context. Further, you don’t always know or understand the expertise of the developers that may run across your code (or how well your future self will remember your current state of mind).

What makes it so hard?

Writing clean code involves striking the right balance of clarity and efficiency. You might be tempted to jam everything into as few lines as possible by using certain shortcuts and clever syntax. But that’s ➕efficiency, ➖clarity. Which can result in fast code and confused developers.

On the other hand, going the extra mile to be clear can potentially have a negative impact on performance. For example, chaining a few array functions together such as map and reduce with the intent of explicitly breaking up your operations so that other developers can clearly see whats going on. This is fine if the array’s size is always a pretty small. It also makes your intent very apparent upon reading. However, if the array can be very large, then you’ve also increased the amount of work being done to achieve a result. Bottom line, there are trade offs to venturing too far towards either end of the efficient-intuitive spectrum.

efficient and intuitive = cash money

It’s definitely a challenge. And the solution or ideas for refactoring aren’t always as straight-forward as the trivial examples above. It’s cliche to say, but with anything practice makes perfect. Always consider your developer friends and think through how to make your code most efficient and most understandable. Overtime you’ll get better at finding the right balance.

A comment about comments.

Blocks of code with tons of inline comments are great candidates for improving with better naming. Very rarely are inline comments necessary. As an alternative, clear and concise logic along with thoughtful naming can explain code without the clutter/noise of comments.

Final Thoughts

There’s 2 types of smart people in this world, those that can explain complex concepts and make them sound simple. And those that can explain complex concepts and make them sound… complex.

I’d vote that most developers would prefer to maintain code written by the former. That kind of code is a joy to use, learn from, read, code review, and maintain. It’s those developers that standout by striking the perfect balance between efficient and intuitive. Keep this in mind as you write your next piece of code! In the same manner that User Experience teams are on the hook for designing intuitive layouts, workflows, etc., as a developer, you’re responsible for the DX, or developer experience of your codebase. To bring this thing on home, I’ll close out with a cheesy catch phrase:

Make a name for yourself, by making a name for others.

Bam💥. Thanks for reading!

For more on naming and other topics regarding clean code, an AMAZING resource (and inspiration for this article) is Clean Code by Martin Fowler. I highly recommend it to any and all developers.

Answer to the question above: the value 3.5 could benefit from a meaningful name. Something like const EXCELLENT_GPA = 3.5;

Stephen White is a Senior Software Engineer with a passion for coding, design, and dataviz. I’m full-stack, but I have the most fun writing clean JavaScript, tweaking styles, and making sh*t look cool 😎.

--

--