Jump to
Press alt + / to open this menu
Join or Log Into Facebook  
Do you want to join Facebook?
Sign Up

Naming From the Outside In

One of the things I love about pairing as much as I am lately is how often people ask me, "Why?" This simple question is often followed by a moment of panic as I realize I don't have a lucid explanation, followed (sometimes) by a thrill because the time has finally come when I can articulate why I do something the way I've been doing it for years.

 

I had one of those moments today. The issue was naming. My partner wanted to name an abstraction after it's implementation. It's natural. You're in the middle of implementing binary search, so you call the function binarySearch. This is where the ummm... stimulating conversation started.

 

Take a step back, I said. Think about this from the perspective of the caller, I said. "Why?" he said.

 

Now, I knew what the function should be called. "fastSearch". That was easy. From the perspective of the caller, that's what distinguishes this search from others. But explaining my reasoning? Hmmm..., "Why?" indeed.

 

After the aforementioned moment of panic and a bit of thought, I came up with two good reasons for naming from the outside in: rates of change and reading flow.

 

I've always paid a lot of attention to the rate at which things change in programs. Things that change at the same rate belong together. Things that change at different rates belong apart. This principle is true of both the data manipulated by the program--two variables that always change at the same time belong in the same object--and the structure of the program--two functions that change at the same time belong in the same class.

 

A corollary to the rate of change is that things that change quickly should be insulated from things that change slowly. In this case, the algorithm used for rapid searching will change more frequently than the need for rapid searching. If I name the function binarySearch, then when I change to a new algorithm I will have to choose between changing all the call sites or leaving a misleading function name sprinkled about. Put another way, the intention "search rapidly" changes more slowly than the implementation "use binary search". I can use a name formed from the intention to insulate the rest of the program from future changes.

 

The second reason I came up with for naming things from the user's perspective is that I want readers of my code to have a smooth transition from understanding what is going on to understanding the implementation. Names chosen from the outside provide this sort of bridge. "We need to search fast. Ah, I see. Binary search."

 

Similarly, readers looking for code to call are more likely to come with needs--I need to search fast--than with a specific implementation in mind. They are looking to search fast, not to find a binary search specifically.

 

So what makes naming from the outside in hard? At the moment you are first choosing a name, you are often in the midst of implementing. Your head is full of implementation details. The metaphors you have been using to get the code to work are all taken from the implementation space. What do we call this? It's a binary search algorithm, so call it binarySearch.

 

Exercise empathy when naming. That was the surprising conclusion from my partner. Take a step back from what you are doing and think about it from a potential user's perspective. Take that nasty "Why?" question and apply it for good--Why is this code here? What benefit does it bring to the caller? I don't know about this function but I'm search for it. What would I guess it to be called?

 

And so, once again, what looks like a technical problem--function naming--turns out to be deeply, personally human, to require human social skills to resolve effectively. I hate that.