A Case for Alphabetization
I have a condition called CDO. It’s the exact same thing as OCD, except the letters are in alphabetical order, as they should be.
Jokes aside, I firmly believe alphabetization is the correct way to organize a codebase, both for parameters in methods and for functions and variables, and hopefully by the end of this article, you will too.
Types of Organization
There are really only three options for organizing your code:
- No order
- “Logical” order
- Standardized rules such as alphabetization
If you don’t see the need to organize your code at all, you probably haven’t even read this far, so for this article, I’ll just be comparing alphabetization versus “logical” ordering. And, because I like making things harder for myself, I’ll work with an example that is commonly used as an argument against alphabetization:
func register(
username: String,
password: String
)
Even as an ardent proponent of alphabetization, I can admit that this order just “feels right,” probably because it’s the order we’re used to seeing in the UI of every website and app. However, even a “straightforward” example like this can descend into chaos as the project grows and context is lost.
Project Growth
Let’s say your project has decided to start gathering more information at registration time. You, the developer, have to expand the register
function to add the new fields firstName
and email
. What order do you put them in?
It would be logical to add them at the end, since they’re new additions:
func register(
username: String,
password: String,
firstName: String,
email: String
)
But it would also be logical to add them in the order they appear in the UI, especially since the parameters were already loosely ordered based on their UI appearance. If the new fields appear after the username field, your function now looks like this:
func register(
username: String,
firstName: String,
email: String,
password: String
)
Already this demonstrates the first instance of why “logical” ordering doesn’t work: different people (or even the same person at different times) can have very different interpretations of “logical” order. Even at this point, this method will appear “logical” to some people but completely unordered to others.
For the sake of argument, let’s say you choose to follow the order of UI, so you go with the second option.
Loss of Context
Now assume there’s been a design update: no functionality is changing, but the name and email fields will now appear before the username field in the UI. This is probably a very simple change to make in the code… of the UI file only. It’s highly unlikely that any developer would make a change in the UI and then think to look through the codebase for any function that might reference the information from this screen just to update the order of the parameters (which should include the function definition, the comments, the tests, etc).
This leads to the second major problem with “logical” ordering: even if it was logical to start with, it’s next to impossible to keep it logical if anything in the project changes at any point, especially if there are multiple people on the team.
Total Loss of Organization
Finally, let’s say there are two new parameters to add to the registration function: an optInToNotifications
toggle that appears after the email but before the username, and an analyticsSource
parameter that does not appear on the UI at all. After scrolling through a few thousand lines of seemingly randomly ordered functions that you assume make sense to the person who wrote them, you’ve finally found the register
method.
Where do you put the new parameters?
If you’re diligent and care about code quality, perhaps you’ll spend a few minutes trying to decipher the current organization so that you can match it. You see that it’s not alphabetical. It’s not related to the UI (anymore). Other methods in the class don’t have obvious organization either. There are no instructions in the project’s style guide or README regarding this. And worse, if you’re not familiar with the codebase (either because someone else wrote it or because it’s been a few days since you wrote it), you might not know why it’s in the order that it is, and therefore you don’t feel comfortable changing it, just in case it’s already “organized” according to someone else. So you have no choice but to tack the new parameters on at the end of the method, which downgrades the codebase from “logical organization” to “no organization at all.”
func register(
username: String,
firstName: String,
email: String,
password: String,
optInToNotifications: Boolean,
analyticsSource: String
)
Why This Matters
As you probably already saw in the example above, unorganized code causes several problems:
- It takes longer to find things. The
register
method in our example is still fairly small, but a method with more parameters or a class with dozens of variables and functions can easily become overwhelming. Looking through six parameters is annoying, but scrolling through a few thousand lines of code can quickly become a major time drain. - It takes longer to find things again. Yes, this is the same as the first point, but it’s worth repeating because you don’t just have to find a method — you have to find it over and over again every time you need it. If you spent any time looking through the UI, other methods, or the README just to try to infer the organization of the
register
method above, you would’ve had to find the method several times, compounding the loss of time. - It takes longer to add or edit things. Trying to infer (or remember) exactly what “logical” ordering the codebase follows takes not only time but valuable mental energy as well. For comparison, an alphabetical organization means you don’t need to spend any time or energy considering how to sort it, since the rule is so simple, objective, and universal.
- It is difficult or impossible to find inconsistencies and maintain a cohesive style guide. By the second step in the example above when the UI changed, our
register
method had already lost its organization. That would have been an incredibly difficult thing to catch in either development or code review. By the time new parameters were added out of order, so much context was lost that it would be difficult or impossible to tell whether the new additions followed the standards of the project. And if there’s no way to objectively evaluate whether code changes follow the standards, how can there be either consistency or a style guide at all? In the worst case, this could even lead to an increased risk of bugs in the code, since it’s harder to spot any irregularities.
Exceptions
Yes, if you choose to organize your code alphabetically, there will be exceptions. For instance, most languages recommend putting optional parameters second and closures at the end, such as:
func register(
username: String,
password: String? = nil,
onCompletion: () -> Void
)
However, there is an important difference between adding a extra rule (i.e., “parameters should be sorted first by required-optional-closure and second by alphabetical order within those categories”) versus making random exceptions to the rules (ie “this parameter was put here because it made sense to someone once”).
There should be a clear and easily definable decision tree for organization that can be kept in the project’s README file so that any developer who works with the code can follow the same patterns and maintain the quality of the codebase.
Conclusion
In conclusion, “logical” ordering is a myth — it is impossible to define or standardize among multiple developers, and over time it will result in the same thing as “no organization” but with extra steps. And disorganization isn’t just inefficient and unpleasant: it’s a productivity killer. So instead, let’s embrace the weirdness of “password, username” and all the simplicity and consistency that comes with it.
Shannon alphabetizes code at Livefront.