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 @
:
@trees = ('Tulip Tree', 'Black Cherry', 'Eastern Redbud');
Variables that hold a dictionary of key-value pairs start with %
:
%abbreviations = (VA => 'Virginia', MD => 'Maryland');
Scalar variables, which hold a single value, start with $
:
$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:
- When a name encodes characteristics of a variable, like its type, that name must be changed whenever a characteristic changes.
- Variable names that start with a narrow set of prefixes will cluster in autocomplete menus, requiring more keystrokes to disambiguate them.
- Modern IDEs make it easier to identify a variable's type without needing to encode it in the name.
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:
(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:
[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:
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:
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:
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:
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:
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 $
:
$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:
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:
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:
class Airplane : Vehicle {
void move(double) {
position += direction;
}
}