Do you ponder what to name things in your code?

by on November 30, 2011

This guest post is by Evan Light a test-obsessed developer, the author of several rarely used gems, and the curator of Ruby DCamp. When he’s not a talking head at conferences, he’s usually working at home as a freelance developer remotely mentoring a developer, working for one or more startups, playing with open source, keeping his wife and four cats company, hacking nonsensically, talking at people on the internet, and/or attempting to lose weight (or any combination of the above). What else do you do when you live 3 hours from civilization?

Why should I care?

Evan Light “The hell with clean code!1, you say. “I’ve got stuff to get done!” You beat on keys for a while. Characters appear. The characters don’t make a lot of sense but, hey, the compiler compiles it or the virtual machine interprets it. Things happen. Eventually, an application emerges.

Success? Hell no!

Most of the time, someone has to maintain that pile of crap you just birthed! It may be someone else. It may be you! But it’s always wise to pretend that the person who will own your code next is an axe-wielding lunatic who knows where you live.

The worst sin that I’ve seen people make in their code: choosing poor names… for their classes, methods, literals, you name it.

“I don’t have time to sit around thinking about the perfect name for a class! Besides, I know how the code works! I can fix it.”

Oh, yeah? You may now. But how about in a month? Or three? Or a year? Wait… will you even be working for this company or on this project in a year? Who inherits this code?

Prototypes, spikes, and other rationalizations

Occasionally, developers invoke the “p” word: prototype. Prototypes are ugly little creatures that live only a short while.

At least that’s the myth.

The truth of the matter is that prototypes don’t exist. Prototypes don’t get thrown away. What happens when you show a manager working code? He says, “Great! Here’s your next feature!”

“But…”, you start to say.

“But what? It’s working! Marvelous! Right, here you are. Next feature!”

Heard of a “spike”? That’s basically a small prototype that you may not tell management about. You spend maybe 30 minutes working on one. The pain of throwing away the code is lessened. But even then it may offend your sensibilities. And that code is going to be ugly too.

We tell ourselves that the code will be temporary. Most of the time, this just isn’t so. These techniques are rationalizations for writing ugly code that will likely outlive its intended lifespan.

Think about the future!

So don’t throw that code away! Don’t prototype. Don’t spike2.

Dave Thomas sometimes describes writing an application as writing a Domain Specific Language. That is, creating an application is akin to developing a semantically meaningful API to describe an application’s behavior.

Therefore, the smartest thing you can do, when starting a new application, is to cultivate an understanding of the overall problem the application is intended to solve.

How can we do this? Personally, I favor contemporary Test Driven Development techniques:

For a given feature:

  1. Describe, in English, what the feature is trying to accomplish
  2. Exercise the API that I wish I’d write as a test
  3. Make the test pass
  4. Compare 1 & 2
  5. Refactor

For instance, consider this simplistic example:

Names should match intent

The English uses the word “subscribe”. That’s the action that I want the user to perform. So I make it the method name because that’s what I want to tell the user to do. That’s the message that I want to send the user.

Now what if I need an entity to representation that relationship between a User and a Plan?

I’ve seen (and written) some egregiously bad code in situations like this. Once upon a time, my initial reaction would be to call such a thing a “UserPlan”.

That’s just vile and disgusting. Sure, it conjoins the two entities but it does so like Siamese twins!

The better answer should be in plain sight. I used the word “subscribe” in the description! Call that entity a “Subscription”!

But maybe your description was

That would probably cause me to write sample code

It’s still valid though I did less to model the relationship between the User and the Plan because words matter and naming matters.

Counter example

So what happens when we name things badly?

Is “UserPlan” so bad? Perhaps not. But UserPlan only represents a relationship between two entities. Perhaps I need a greater monstrosity to make the point plain.

So what is a SelfpropelledFourWheelGroundVehicle? It’s pretty plainly a Car/Automobile. But it’s a disgusting name. Yet these are the kinds of names that people frequently use in their code due to lack of effort!

Or there’s the other direction: Haskell developers often like to abstract functions such that they have no clear applicability to a domain. That is, their functions will have semantically meaningless variables such as “x” and “xs”. I’m told this is because Haskell has its roots in Lambda Calculus. Be that as it may, mathematical variables have only place in code: in implementing a mathematical calculation!

How would you feel maintaining code where the classes, literals, and methods read like that?!

How productive would you be working in such code? If you cannot trust the names in a code base to accurately represent the ideas at work then you need to understand vast swaths of the code base to be the least bit productive!

Conclusion

If you did not before, I hope that you now have a better appreciation why it is worth your time to get the names right in your code. It will make yours, your colleagues’, and any who later touch your code lives better and more productive.

And if you don’t use good names, I have an axe and I know where you live.

I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post. Thanks!

Subscribe to the waiting list of the free, online “Intermediate Ruby Course“.

Technorati Tags: , ,

  1. Robert Martin also wrote about this topic, and, in part, inspired this diatribe with the first chapter of his book, Clean Code.
  2. Yes, this is a sweeping generalization. Yes, I occasionally spike on code. However, I only do this for technically challenging pieces which is to say very infrequently. And I throw my few spikes away.
Posted by Evan Light

Follow me on Twitter to communicate and stay connected

{ 11 comments… read them below or add one }

Hugo Estrada November 30, 2011 at 6:43 pm

Thanks for the article; it is worth to be reminded by this principle every so often. It is worth saying also that changing names is one of the easiest refactoring steps anyone can do. The code doesn’t change, but the understanding of the code for the reader improves significantly.

Reply

Jonathan Jackson November 30, 2011 at 7:48 pm

I can’t tell you how much this article resounds with me. I’m reminded of an article by Mark Slagell where he talks about object oriented programming. He mentions how we should treat objects/data as if they were sealed machines with well labeled switches and dials. This concept of object orientation revolves around the _well labeled_ part.

Also if anyone needs evidence of how naming affects your ability to maintain programs just try to debug a perl script.

Reply

Pat Shaughnessy November 30, 2011 at 8:17 pm

Great write up Evan! We’ve come a long way from “Hungarian notation!” … remember those days? :)

Reply

Brian Cardarella November 30, 2011 at 9:13 pm

There is a great paper on this subject: http://www.objectmentor.com/resources/articles/naming.htm

Reply

Dave Aronson December 1, 2011 at 3:09 am

A-friggin’-men! A couple months ago, I waded through a draft of Odersky’s “Scala by Example”, and that ‘semantically meaningless variables such as “x” and “xs”’ crap was all over it, with no explanation of WTF that difference was supposed to mean. Seems like he uses x for scalars (no pun intended), xs for arrays, xss for arrays OF arrays, and so on. Coulda just used x, arr, and grid, or something like that.

C’mon, guys, this isn’t 1970′s BASIC any more, we can use more than two chars for a varname! :-P

Reply

james December 1, 2011 at 11:30 am

+1 on ObjectMentor paper

Also, try taking the word “should” out of your specs for a nice surprise. Tangent-al I know.
eg: it “should be able to subscribe to a plan” might be more succinct and
meaningful ….

it “subscribes to a plan”
it “subscribed to a plan”
it “has subscriptions”

Reply

Nuwan Chaturanga December 1, 2011 at 1:48 pm

Great post on this very important practice.

Sometimes I spend more time to come up with a good name for a class or a method than I spend to implement it.

Reply

belun December 2, 2011 at 8:42 pm

“Describe, in English, what the feature is trying to accomplish” + make sure it’s only one feature (the naming stage might be used as safe guard against multiple ‘features’ or poor design)

Reply

Evan Light December 2, 2011 at 9:35 pm

Ah now that’s an entirely different topic though a favorite of mine: TDD.

Reply

itoctopus December 3, 2011 at 6:24 pm

Yes,

I do ponder on what to name things. The task sometimes become harder when I need to name something that is similar to another thing.

I need a another total amount, shall I go with totalAmount2? Or shall I rename the first totalAmount to something else?

Reply

Evan Light December 3, 2011 at 10:12 pm

Generally, you don’t want a totalAmount an totalAmount2. They are almost certainly totals in two different contexts. What are those contexts? Try to find a way to get the context into the name.

Reply

Leave a Comment

{ 51 trackbacks }

Previous post:

Next post: