Naming Practices

Dear Computer

Chapter 2: Naming Things

Naming Practices

Names have varying levels of significance in programming languages. Sometimes a name is significant only to the humans reading the code. At other times a name has semantic bearing that alters how the program behaves.

Casing Conventions

Multiple-word names are generally formatted according to the preference adopted by the language's community of users. The Java, JavaScript, and C# communities use lower camel-case for variables and methods (kittensPerLitter) and upper camel-case for classes (FeaturedVideo). The C, C++, Ruby, and Python communities use snake-case for variables and methods (kittens_per_litter) and upper camel-case for classes. The HTML, CSS, and LISP communities use kebab-case: kittens-per-litter. There are several other casing schemes.

Casing conventions are just that: conventions. They are not hard and fast rules. Nonetheless, collaborative development is easier when programmers agree on naming practices. Many companies expect employees to adhere to an established style guide, such as Google's Java Style Guide.

Prefixes and Suffixes

Sometimes a variable name is preceded by special characters that denote some quality of the values it may hold. In Perl, variables that hold an array start with @:

Perl
@trees = ('Tulip Tree', 'Black Cherry', 'Eastern Redbud');

Variables that hold a dictionary of key-value pairs start with %:

Perl
%abbreviations = (VA => 'Virginia', MD => 'Maryland');

Scalar variables, which hold a single value, start with $:

Perl
$ratio = 1.618;

In Ruby, instance variables in a class start with @, static variables start with @@, and global variables start with $.

Some companies, including Microsoft and Xerox, have at some point in their history followed a naming convention called Hungarian notation. In Hungary, family names appear first and given names second. Likewise, in Hungarian notation, a variable's name starts with information about its family or type. A string may be named sName or a count may be named nPeople. Strict adherence to this notation is generally no longer recommended for several reasons:

Programmers occasionally decorate a name with an underscore to denote that a variable is private and should not be accessed directly by external code. Google, in its JavaScript style guide, recommends adding an underscore suffix to avoid the common prefix issue. The underscore, whether prefix or suffix, is not a universal practice. AirBnb's style guide forbids it.

Predicates are expressions that answer a question about an entity with a boolean response. Is the user input a valid number? Does the string contain spaces? Does the file exist? In the Lisp family of languages, predicate methods are often named with a question mark suffix, like this:

Racket
(number? "infinity")   ; yields false

This isn't possible in many languages because the lexer does not recognize ? as a legal identifier character. Most names in Ruby cannot use ?, but method names are an exception. They may have a trailing ? to indicate that they are a predicate. For example, several collections have methods for checking whether a value is in the collection:

Ruby
[1, 2, 3].member?(2)               # yields true
{first: "Simon"}.has_key?(:last)   # yields false

Predicates and boolean variables also sometimes start with is, has, wants, needs, or some other linking verb to make the program logic more pronounceable. This pairs well with the dot notation found in many object-oriented programming languages, which produces a subject-verb-object ordering, as shown in this logic that rebuilds an executable when a dependency has been updated:

Ruby
if dependency.is_newer?(executable)
  executable.rebuild
end

Abbreviations

In early versions of Fortran, variable names could not be longer than 6 characters. In C and later versions of Fortran, names could not be longer than 31 characters. In some versions of BASIC, only the first two letters of variable names were significant. These limits, along with small terminals and a tendency for experts to not recognize their inscrutability, have inspired many programmers to use abbreviated variable names like medInsAmt. Modern style guides, such as the .NET documentation from Microsoft, recommend pronounceable and readable names and discourage abbreviations. However, there's no consensus. The Go community, for example, encourages single-letter names—but only for variables with a small scope and a short lifetime.

Constants

Constants are variables that are not meant to vary. Once initialized, they cannot be reassigned. In many languages, the names of constants are often written in screaming snake-case: entirely in capital letters, with words separated by underscores. The OpenJDK implementation of Java's ArrayList class defines a constant for the initial size of its backing array:

Java
private static final int DEFAULT_CAPACITY = 10;

The casing of constants is only a convention in many languages. In Ruby, however, a leading capital letter is exactly what triggers the interpreter into designating the variable as a constant. Ruby's builtin Logging::Formatter class defines its format strings as constants:

Ruby
class Formatter
  Format = "%s, [%s #%d] %5s -- %s: %s\n"
  DatetimeFormat = "%Y-%m-%dT%H:%M:%S.%6N"
  # ...
end

Constants in Ruby may be declared at the top-level of a class, script, or module. What happens if you try to define one inside a function?

Presumably you can't define constants in methods because Ruby stores constants at a higher scope than the method. Assigning a constant within a method would therefore result in reassignment on every call, violating the semantic meaning of constants.

Globals

This Ruby script has an error:

Ruby
prompt = "> "
def input
  print prompt
  gets.chomp
end

Can you guess what the error might be? The section heading may provide a clue. The variable prompt is not visible in the method. Methods in Ruby may only access local variables, parameters, and globals, and prompt is none of these. In fact, there are two different prompt variables in the script, both local. The first prompt is defined at the top-level, and the second inside the input method. One fix is to make the prompt a constant by capitalizing its first letter, which makes it also global according to the semantics of Ruby:

Ruby
Prompt = "> "
def input
  print Prompt
  gets.chomp
end

But global and constant are separable qualities; you may want a global that can be changed. A non-constant global variable in Ruby must start with $:

Ruby
$prompt = "> "
$prompt = "you: "
def input
  print $prompt
  gets.chomp
end

Unused Names

Sometimes a programming language will force you to give a name to a variable or a parameter to which you don't intend to refer. Other languages allow you to leave it unnamed. In Kotlin, for example, you may discard a variable by “naming” it _. Consider this program that creates a pair of Cartesian coordinates and then destructures it, naming only the y-coordinate:

Kotlin
fun main() {
  val coordinates = Pair(3, 4)
  val (_, y) = coordinates
  println(y)  // prints 4
}

The unused x-coordinate is not given a name. Haskell, Scala, and Rust also interpret _ in this way.

In C++, suppose you are overriding a method from a superclass, and the superclass imposes parameters that are not relevant to the subclass. For example, this Vehicle class introduces a move method that accepts a bumpiness parameter describing the quality of the terrain:

C++
class Vehicle {
  virtual void move(double bumpiness) {
    position += direction / bumpiness;
  }
}

The Airplane subclass does not travel on the terrain, so the bumpiness parameter is useless. Yet move must conform to its interface. To make it clear that a parameter is unused, you leave off the parameter's name in the method header:

C++
class Airplane : Vehicle {
  void move(double) {
    position += direction;
  }
}
← von Neumann ArchitectureSymbols →