Daily Archive for March 10th, 2009

Naming Conventions

Here’s a quick review of the naming conventions I’m using right now. I am not going to dive into silly cosmetic issues such as making some letters uppercase or using some underscores or prepending warts, because usually every project has their own writing conventions: if you use the Zend framework, you probably want to use the ZF conventions, if you use the C++ with boost, you probably want to use the SC++L/boost naming conventions, if you use C# and .NET you probably want to use the .NET naming scheme, and if you use Objective Caml you will be shoehorned into writing conventions as well.

But these conventions usually tell you how to place uppercase letters and underscores inside variable, function, class, label and module names. They do not tell you what words those variables should be made of. This is what my personal naming conventions bring to the table: a choice of words that’s reasonably standard. Here are some examples you can find in my code:

Basic Names

If the domain provides a simple and clear name for my variables and functions, I will use it. This happens very often in straight down-to-earth code that just does what is expected without any performance improvement attempts. It will be using names such as “username“, “page“, “reply“, “target” or “missile“.

And if your choice of type names is equally sane, you will end up with variables looking like “Missile missile“. There’s nothing inherently wrong with this—as long as the context gives enough information about why this missile is important.

The technical names that match required knowledge are also fair game. For instance, if your code uses a MySQL database, then it’s acceptable to assume that the reader will have to know about MySQL-related concepts and thus the corresponding names can be used. This makes “row“, “field” and “query” acceptable names in that context.

Be aware of collisions! If your program manipulates both domain-level queries (such as a query from a user) and implementation-level queries (such as a query for the database), the default interpretation whenever both contexts are possible is the domain-level one, because this is the one that readers will have in mind most of the time.

Context

Depending on where the name is used, its meaning can be different.

Class members usually have an implicit “of” meaning: “user.Name” is the user’s name without a shadow of a doubt. This is why, for instance, I would never hesitate to use a variable with the same name as its type as a member variable: the fact that it’s a member variable adds some information about it. Plus, in languages without type annotations (OCaml and PHP, for instance), it gives the reader some information about the type.

The same happens with function parameters, which have an implicit “to be processed” meaning. A function which computes the balance of an account can certainly have a self-explanatory parameter of type “Account” named “account“.

And, of course, loop variables in for-each loops also have an implicit “in the collection” meaning.

Modifiers

  • fooCount : the number of “foo” elements within the context where the name appears. This is always an unsigned integer (or as close to an unsigned integer the language allows). For example, article # visitor_count would return the number of visitors of an article, and $errorCount would be the number of errors encountered by a function so far.
  • fooBarRatio : the proportion of “bar” objects within the context that have the “foo” property. This is always a floating-point number, and is usually equivalent to dividing fooBarCount by barCount. For example, TaskManager::FailedTaskRatio() returns the proportion of failed tasks among the tasks handled by the task manager.
  • foos : a sequence of “foo” elements. This is usually the language’s simplest representation of a sequence, such as an array or list. For example, article # authors is a sequence of authors.
  • fooIsBar : a boolean indicating whether the “foo” has the property “bar“. The “foo” may be implicit. For example, errorIsFatal indicates whether an error is fatal, and article # is_visible indicates whether an article is visible. I do not use “has”, because if an object may optionally have a certain something, that something should be an optional property using language support for optional values.
  • fooByBar : an associative container which allows retrieving a “foo” value associated to a “bar” valule, or a function which performs as an associative container retrieval. The “foo” may be implicit in exceptional situations. There’s no guarantee, of course, that a key has an associated value. For example, User::ByName finds and returns a user by its name.


1170 feed subscribers
(readers who polled a feed this week)