The Importance of Naming Variables

A case for why concise code is not always better than more verbose code.


I think one of the most overlooked aspects of programming is the importance of what variables are called. I think the because creating variables is one of the first things programmers learn, if not the first thing they learn, it is a common misconception that because it's not hard to do, it's not hard to do well.

My personal belief is that a telltale sign of an experienced programmer is how aptly they name their variables and functions. After all, these names are the first insight into revisited code. Well named functions don't need comments and well-named variables don't need explanations.
Someone who has spent time working through needlessly complicated code is hopefully someone who will give the person that comes after them, an easier time, and an 'easy' way to do that is through clearly named variables as well as good function names.

Code should be easy to read, easy to reason about and intentions should always be clear.

Take this short example for instance:

Imagine we have a list of users with their orders.

If they are an active user who has ordered a particular item more than once, then they qualify for automatic entry into a competition.

  
// given a function that returns a data structure for users and their orders;

function get_users()
{
	return [
		[
			"id" => 0,
			"name" => "Daniel",
			"active" => false,
			"orders" => [
				[
					"order_number" => "0003",
					"line_items" => [
						[
							"product_code" => "1337",
							"quantity" => 10,
						]
					]
				],
			]
		],
		[
			"id" => 2,
			"name" => "Natasha",
			"active" => true,
			"orders" => [
				[
					"order_number" => "0008",
					"line_items" => [
						[
							"product_code" => "777",
							"quantity" => 3,
						]
					]
				],
				[
					"order_number" => "0009",
					"line_items" => [
						[
							"product_code" => "1337",
							"quantity" => 1,
						]
					]
				],
			]
		],
		[
			"id" => 3,
			"name" => "Bryce",
			"active" => true,
			"orders" => [
				[
					"order_number" => "0010",
					"line_items" => [
						[
							"product_code" => "xyz",
							"quantity" => 10,
						]
					]
				],
				[
					"order_number" => "0012",
					"line_items" => [
						[
							"product_code" => "1337",
							"quantity" => 4,
						]
					]
				],
			]
		]
	];
};
  

You could write a single function that does this like so:

  
function users_that_qualify_for_competition() {
  $users = [];
  foreach (get_users() as $u) {
    if (!$u['active']) continue;
    $count = 0;
    foreach ($u['orders'] as $o) {
      foreach ($o['line_items'] as $i) {

        if ($i['product_code'] === '1337') {
          $count += $i['quantity'];
        }
        if ($count > 1) {
          $users[] = $u['id'];
        }
      }
    }
  }
  return $users;
}
  

Less is not always more

This above function does work,
and it does what you need, but give yourself some time and you may forget all about it, or if a new dev works on the project, he has to now spend maybe longer than needed figuring out what the function is doing.
Concentration in the day is a finite resource, so you should try and conserve your own and others as best you can.

In my opinion, your best defence around any issue like this is naming variables properly and splitting logic into clear single-purpose functions .

That's why I propose a better solution would be something more along the lines of:

  
function order_passes_auto_entry($order)
{
	$qualifyingProductCount = 0;
	$qualifyingProductCode = '1337';

	foreach ($order['line_items'] as $line_item) {
		if ($line_item['product_code'] === $qualifyingProductCode) {
			$qualifyingProductCount += $line_item['quantity'];
		}
	}

	return $qualifyingProductCount > 1;
}

function user_passes_auto_entry($user)
{
	if (!$user['active']) return false;

	foreach ($user['orders'] as $order) {
		if (order_passes_auto_entry($order)) {
			return true;
		};
	}

	return false;
}

function user_ids_for_auto_entry($users)
{
	$user_ids = [];
	foreach ($users as $user) {
		if (user_passes_auto_entry($user)) {
			$user_ids[] = $user['id'];
		}
	}
	return $user_ids;
}
  

More can be more

I propose that the above solution is a better one then the previous solution. While it may be far more verbose and twice as many lines, the intention is much clearer and the functions easier to test.
Shorter code, is not always better code.

The time you'll save typing is often far less then the time you'll save yourself later when working on your code again in the future.

It can often be silly to shorten variable and function name length, when your editor completes the symbol most of the time.

DON'T GET ME WRONG
Concise code is great!
I often find myself writing shorthand functions like so:

  
    const boxers = dogs.filter( d => d.breed === 'Boxer')
  

The intent here is clear.

What I won't do is something like:

  
    const fn = `Daniel Amber`.split(' ')[0]
  

fn as a variable name is far too ambiguous.
fn could be short for 'function', 'first name', 'favourite name' or 'freaky nerd'.
In this situation there is pretty much no reason not to name the variable firstName.

Also:

Avoid double negatives

Reading code with a '!' operator before a negative variable name is very jarring.
So do whatever you can to avoid writing code like this:

  
    const dont_delete = ['file_1', 'file_2'].includes(file_name)
    if (!dont_delete) {
      // delete...
    }
  

Let the variable type be inferred from it's name

I've worked on code before where the first letter of the variable type was the first letter of the variable name.
For example and array of names would be $aNames or a string for a name would be defined as $sName.
The idea here was that it would be clear what type of variable type you had when you passed it around. It was before you could do strict typing in PHP.
Regardless... variable types should be inferred from how they are named. $names is a plural. That is enough to infer it is an array.
The var $name gives you enough info to infer its a String.

If the you are working in a dynamically typed language and you feel that the type of your variable may be ambiguous, it's a sign that you can probably name it better.

When it comes to programming intention and reasoning are tantamount.
It's a slippery path when you start naming strings s and floats f.
Always think about the person looking at your code after you, or you looking at it later down the line.
There is less need to rely on comments when code is written to be clear and understandable.