Thursday, January 28, 2010

Code #region considered harmful

I simply hate #regions. Apparently I'm not alone.

In C#, a bit of code surrounded in #region...#endregion markers is folded shut by any decent IDE. The code becomes invisible until you ask to see it. This sounds like a good idea, but it really is not. It makes code *look* smaller, but the code is not smaller. It is more of a girdle than a diet. The code is instead better-hidden, an attribute I can hardly describe as a virtue.

There are plenty of reasons to hate long methods and long classes. The foremost is that you cannot see and grok them at a single glance. The programmer needs to read code quickly without misunderstanding it. The #region tag is one of the most sure-fire ways to make that problem considerably worse. The region worsens most of the problems long classes and long methods cause.

The #region is almost certainly an American or British policy decision. It makes things seem better while all the time making them considerably worse. Whenever we prefer 'seeming' to 'being' we have taken a wrong turn. It is like the alcoholic who hides his booze so he can seem fine while drinking heavily in secret.

Take off the #region tags and look at your code in the clear light of day. Does it seem like it doesn't belong there? Move it instead of hiding it. Does it seem like too much boilerplate? Then cut down your framework so it demands less of you. You can make your system better, instead of hiding the dirt. Really.

Name it Badly

If you cannot name something well, then please name it appallingly badly. No, this is not a joke about the iPad.

When I am stuck for a name, the problem usually not my command of English or lack of a good Thesaurus. It is that either I don't know what kind of a thing I'm applying the name to, or it is in the midst of morphing from one kind of thing into another. In such cases, neither can my pair programming partner name it. Its identity is unclear. Yes, this is about the Single Responsibility Principle again.

A class with a clear single responsibility (does it all, does it well, does it only) is easy to name. Anything with a responsibility that is not clear, not complete, or is mixed with other responsibilities is going to be hard to name. Anything that can't have a good name should have a bad name. A very bad name.

Most of the rules still apply. You want something greppable, something that isn't going to disinform, and something that is pronounceable (etc). What you don't want to do is give it a name that is plausible and professional. DataUpgradeManagerClass is appallingly bad, but someone might take it seriously for just a minute or two, and might hesitate to rename it.

Some people like to embed a WTF in the name, as in WTFNames or ListOfWTF. I guess that's okay. Nobody will look at it and think it is something official and well-named. I personally like "Thing" or "Thingy" or "Doodad". I have named tests and variables after my programming partners. I have named them with nonsense words. I have given them joke names. When you see what I've done, you know I'm stuck for a name.

The point is not to leave the object unnamed, and not spend the next 20 minutes trying to name it. Throw on a stupid temporary name until you can think of something better, like when the class has found its single responsibility or has been broken into several classes which each are singly-responsible. As long as the name sticks in your craw just a bit, you are more likely to rename it. This will help prod you to rethink the strange things so-named.

I went for a week with a test suite that had a bad name, in a file called Class1.cs. We knew it was badly named, but our tests were scattershot and begging for reorganization. When we pushed the code, the suite was well-named and was organized into test classes which were named after testing scenarios, and the methods were consistent and meaningful. We were letting the code shape itself and lead us, so we could not pretend to know where we were really going. By putting stupid names in, we were able to keep going until we knew what we were into.

You should not push the code with stupid names. This means that you might want to search your conscience or maybe your diffs prior to pushing code. Pushing code that has some appallingly bad names means that you pushed code that has ill-formed thoughts in it, and probably ill-formed classes. Have I pushed badly-named code? To my shame, yes. Both I and my partner at the time forgot. I really need to read my own diffs more often.

If you do push with a stupid name, however, be assured that your other teammates will let you know. All the good version tools have a blame or annotate function, so they'll know it was you or your partner. I'm the guy who wrote "TheWillieTest" and "DeleteMe" in the same week.

Technically, DeleteMe was an intention-revealing name which I'd put into a file temporarily to help me explore some syntactic issue and opportunities. I accidentally did leave it in, and did not review my diffs (sigh) and when Ryan (my coworker) found it he knew just what to do. He deleted it. And tweeted it. And I blushed.

Bad naming is a tool, just as good naming is a tool. Seriously consider how appallingly bad names might help you produce code without obsessing on names for coding artifacts that have unclear identities. If you use appallingly bad names, though, it might pay you to review your diffs just in case.

Wednesday, December 30, 2009

Easy to Use

I'm working in multiple tools and languages lately. It set me to thinking about what makes one better or worse than another. About the same time, I see a lot of mentions of yak-shaving hassles and OS reboots on twitter. I hear a lot of complaints about one feature or another of an ide, editor, or operating system and how they impede programmers from making software.

We advise people to stop measuring "agility" in agile orgs and try measuring whether you have a better flow of useful, high-quality software. In the same vein perhaps we should measure tools by whether they get things done rather than by counting features and corporate supporters. Are we getting more done?

A tool can be described as "productive" if it avoids adding obstruction to your workflow. If I want to do something, I am either allowed to do it easily (transparent tools) or I am impeded from doing it (unproductive tools). If I have to switch languages and contexts several times (as with java environments) then I'm impeded. If I can simply do what I wish (as with most python environments) then I'm productive.

This goes with cognitive load as well. How much do I need to know and hold in my head at one time in order to successfully navigate a complex system? The less I have to carry around implicitly in my head, the more I can focus on what I want to do. A counter example would be editing XML for an ORM, and then coding C# in a multi-tier architecture of classes, then XHTML for a web page, and then back to C# code for custom tags, and then a dive into javascript and some CSS changes to make it look nice ... adding a simple text field to an application may involve considerable impediment and travel between files, even if it is a "simple" store-and-report field.

As regard tools, the more quickly I can put ideas from my head into the code (ie. refactoring tools in Eclipse or Resharper) the more productive the tools are. The more the tools cause me to go somewhere else or type more or navigate mouse-and-menu, the less productive it feels. The more I have to switch between editors and languages to do a single job, the less productive it feels. Odd that I consider Java to be less productive than some other languages, and consider eclipse to be a highly productive environment. I guess it grew where it was needed.

The same idea goes with code. How much of it do I have to read (or reverse-engineer) in order to know what it is doing and whether I'm in the correct place to make a change? I've certainly dealt with code that gets in its own way until I am not sure whether I am even in the right place to make a change. By having temporal coupling, tuple madness, poor decomposition (no "centers"), or detail-heavy control routines, the code impedes my navigation. I want to know where to go to make a change. I want to get in and out quickly without any severe misunderstandings. I want to be productive. Good code allows me. Poor code impedes me.

I am debugging a tool. It has oblique error messages, so I have to dive into the code to reverse-engineer the issue. The error messages are non-specific so I have to modify them them and re-run the code so that I can see and correct the problem. The more specific the error message, the less I have to do to get my work done. The more oblique and detail-free, the more yak-shaving research I have to do.

That being said, I do understand that a mix of skills is necessary at this point in time. I think that (X)HTML and templating languages and CSS are perfectly good skills and highly necessary. I am just pointing out that the mix can make it harder to do web development tasks than some other non-web programming tasks, and that the toolkits are not to a point where simple things are truly simple. Likewise, I appreciate the advances in ORMs while noting the additional cognitive load involved. Sometimes it is easier to simply write a gateway object that interacts with good ol' SQL.

Now I understand why Google's search page is so brilliant as a consumer product. There is nothing I have to learn before I can use it. It gives me a clear message about my mistakes ("did you mean weird science?"). It provides me the minimal impediment. Likewise, I see how a lot of other web apps have failed. They crowd the space with many controls that obscure the few controls of interest, they provide little useful information in the error messages, they require too much yak-shaving (multi-page nonoptional wizard madness), they have funky implicit prerequisite structures that make one back out of a task and restart from a new initial state.

Especially as regards consumer-facing software, less is really more, and we should learn how to maximize the amount of work not done by users. Does it really take a four-page registration, a memorized secure password, and/or waiting through a flash greeting page to view "publically available" documents on your web page? How hard is it to opt out of a mailing or cancel service? How many forms and navigation pages does it take to extract some value from the web app you're building?

One final note: tools like vim and emacs *become* pretty transparent when you've been trained to them (as are Eclipse, NetBeans, and Resharper for VS.NET). You end up memorizing keystrokes, techniques, and tactics. You build up a library of magic tricks. These tools are transparent to experts in their use while being a pain for novices to pick up. They move from impediment to transparency over time.

Monday, December 14, 2009

Pauses

An astute reader might notice that all my blogs are currently languishing. There are reasons for this, from my father's massive stroke to my continually-delayed house closing, to other crises in my family (biological and ecclesiastic) that have my attention though there is little I can do about any of these things.

Who knew that doing nothing and having nothing doable would be so taxing? That instead of neatly compartmentalizing things away as "to do later" and moving on, that one would be sapped of passion for work and learning and communicating? Still, this is how things are right now. As we move into Christmas time and the new year, I have little to advise in the way of agile practice and code cleaning right now.

On the other side of the bright and shining holidays and the various crises, I hope to have more to give you. I thank you for your patience.

Update

We closed on the house on Dec 17, and have been moving over the holidays. There have been surprises and disappointments, but we're getting it done. It is consuming a lot of our lives, and especially my oldest son's winter break from college. Hardly what anyone had in mind.

My sister's family has been taking care of all of the arrangements and hard work regarding my dad and mom, and has them safely moved into care facilities according to each one's needs. Sadly, they can't be together yet, though dad is showing some improvement. He may never be self-sufficient again, but he is a man of many surprises and won't be counted out.

I hope to be back here soon, and have some new ideas for Agile In A Flash. February should see a big increase in my online activities.

Friday, December 4, 2009

A Waste Of Vertical Space

I'm getting really frustrated with code that pointlessly burns vertical space when I'm reading in a window in an IDE (in this case a C# type of IDE). I need to take in ideas at a glance as I survey this code, but people seem to not appreciate the "at a glance" qualities I treasure.

To wit: Do we really need 18 lines for each of the delegate's exposed properties?


/// <summary>
///
/// </summary>
/// <returns></returns>

public string GetSomeValue() {
return delegate.GetSomeValue();
}

/// <summary>
///
/// </summary>
/// <param name="value"></param>

public void SetSomeValue(string value) {
delegate.SetSomeValue(value);
}



Each three-line statement has 8 lines of worthless comment and unnecessary vertical white space around it.

I won't argue one way or the other about the need for parallel hierarchies of exposed classes delegating to hidden classes here. I've even left off the fact that there is gratuitous context being used in the real code (I've cleaned this up for your convenience). Ignoring all the other bits of silliness or grand architectural idealism, let's just talk about this very small bit of code.

Why not use this:

public string SomeValue {
get { return delegate.GetSomeValue(); }
set { delegate.SetSomeValue(value); }
}


I think we gain readability by deleting 15 lines of fluff and reducing the namespace pollution by half. The operations group more naturally, so I don't have to remember to mentally group getters and setters. I know that they're going to (and coming from) the same place. And best yet, that little snippet fits in my paltry IDE window.

Spreading a small bit of code out over a large area seems like rude behavior to me.

Okay, I've ranted. Thanks for the time. I'm back to the code.

Thursday, December 3, 2009

Tech Upgrades for The New Year

I am replacing my old, dying laptop with a NoteBook (ASUS Eee PC 1005MA) but that's not what I'm talking about here.

I need to upgrade my tech *skills*. It is time for me to go waist-deep into the air, flash, javascript world. I need to get some skills with making hot web sites and making them look hot. Oh, there is more basic training needed in color and design, but I want to be able to do the technical side of it for now.

I'm going to dive in with a project, I think. Django behind, javascript up front. Then I need to look at air, flex, etc. This could be the year that I make my work more visible.

It will be fun learning to test-drive (or learning how to cope with not test-driving) these new languages and getting into the mindset of this whole trial-and-error UI world. But it should be exciting, and now that I've declared it on my blog I have to make it happen.

Watch this space.

Tuesday, November 17, 2009

Gratuitous Context

I have been working on code that oscillates between cryptic abbreviations and absurdly long names in functions. Sadly, I cannot reproduce it here for you, or I would. The problems with cryptic abbreviations I have hammered before, so my opinion is well-known (stp bng stngy nd us sm stnkng' vwls, k?). I don't talk enough about gratuitous context.

A name needs to be meaningful in context. The context of a class includes its namespace, the context of a method or class variable includes its class, the context of a method argument includes its method name, and the context of a local variable includes the method that encloses it. This context is cumulative as you navigate namespaces to classes to methods to method inners.

One thing that really is annoying is to see Grouping.Group.MakeGroup(string GroupName) with local variables that all include the prefix "Group". This is gratuitous context. This kind of naming actually hurts the readability of a program.

In a previous article I mentioned three concerns that will affect naming. In this case, we see that a local variable will be close to its point of declaration, and that there are very few variables in play. In this context, all the names are used fairly frequently and never outside of the method. All of these forces drive us to small, easily-recognized names.

Sticking the word "group" on the front of every name not only is unnecessary, it causes the eye to search farther into each word to tell the variables apart. While this is hardly a strenuous effort, it is enough of an effort to cause the reader to exercise extra care in reading instead of taking in the code in a glance.

The contextual prefix also means that the auto-completion of your editor/ide/whatever will pop up a list of names and yours is unlikely to be the first candidate. With a list of similar names, you must exercise additional care to be sure you do not accidentally pick the wrong variable from the list. This is becoming a fairly common type of programming error these days. Usually a pair programming partner will be able to tell that you have picked the wrong variable even if you do not notice it yourself, but this is again wasted effort.

In naming, a long name is not automatically better than a short name. Clarity is the goal. Sometimes longer names are harder to differentiate, which makes them less clear than shorter names, and a long bad name is worse than a short bad name.

For more on this topic, please see Chapter 2 of Clean Code, or the less polished version at my older blog and/or the earlier article the Long and Short of Naming.