It’s all about context

The C# using directive and implicitly typed local variables (i.e. using var) are Good Things whose use should be encouraged in C# programs, not prohibited or severely limited. Used correctly (and it’s nearly impossible to use them incorrectly), they reduce noise and improve understanding, leading to better, more maintainable code. Limiting or prohibiting their use causes clutter, wastes programmers’ time, and leads to programmer dissatisfaction.

I’m actually surprised that I find it necessary to write the above as though it’s some new revelation, when in fact the vast majority of the C# development community agrees with it. Alas, there is at least one shop–the only one I’ve ever encountered, and I’ve worked with a lot of C# development houses–that severely limits the use of those two essential language features.

Consider this small C# program that generates a randomized list of numbers from 0 through 99, and then does something with those numbers:

    namespace MyProgram
    {
        public class Program
        {
            static public void Main()
            {
                System.Collections.Generic.List<int> myList = new System.Collections.Generic.List<int>();
                System.Random rnd = new System.Random();
                for (int i = 0; i < 100; ++i)
                {
                    myList.Add(rnd.Next(100));
                }
                System.Collections.Generic.List<int> newList = RandomizeList(myList, rnd);

                // now do something with the randomized list
            }
            
            static private System.Collections.Generic.List<int> RandomizeList(
                System.Collections.Generic.List<int> theList,
                System.Random rnd)
            {
                System.Collections.Generic.List<int> newList = new System.Collections.Generic.List<int>(theList);
                for (int i = theList.Count-1; i > 0; --i)
                {
                    int r = rnd.Next(i+1);
                    int temp = newList[r];
                    newList[r] = newList[i];
                    newList[i] = temp;
                }
                return newList;
            }
        }
    }

I know that’s not the most efficient code, but runtime efficiency is not really the point here. Bear with me.

Now imagine if I were telling you a story about an experience I shared with my friends Joe Green and Bob Smith:

Yesterday, I went to Jose’s Mexican Restaurant with my friends Joe Green and Bob Smith. After the hostess seated us, Joe Green ordered a Mexican Martini, Bob Smith ordered a Margarita, and I ordered a Negra Modelo. For dinner, Joe Green had the enchilada special, Bob Smith had Jose’s Taco Platter . . .

Wouldn’t you get annoyed if, throughout the story, I kept referring to my friends by their full names? How about if I referred to the restaurant multiple times as “Jose’s Mexican Restaurant” rather than shortening it to “Jose’s” after the first mention?

The first sentence establishes context: who I was with and where we were. If I then referred to my friends as “Joe” and “Bob,” there would be no ambiguity. If I were to write 50 pages about our experience at the restaurant, nobody would get confused if I never mentioned my friends’ last names after the first sentence. There could be ambiguity if my friends were Joe Smith and Joe Green, but even then I could finesse it so that I didn’t always have to supply their full names.

Establishing context is a requirement for effective communication. But once established, there is no need to re-establish it if nothing changes. If there’s only one Joe, then I don’t have to keep telling you which Joe I’m referring to. Doing so interferes with communication because it introduces noise into the system, reducing the signal-to-noise ratio.

If you’re familiar with C#, most likely the first thing that jumps out at you in the code sample above is the excessive use of full namespace qualification: all those repetitions of System.Collections.Generic.List that clutter the code and make it more difficult to read and understand.

Fortunately, the C# using directive allows us to establish context, thereby reducing the amount of noise in the signal:

    using System;
    using System.Collections.Generic;
    namespace MyProgram
    {
        public class Program
        {
            static public void Main()
            {
                List<int> myList = new List<int>();
                Random rnd = new Random();
                for (int i = 0; i < 100; ++i)
                {
                    myList.Add(rnd.Next(100));
                }
                List<int> newList = RandomizeList(myList, rnd);

                // now do something with the randomized list
            }
            
            static private List<int> RandomizeList(
                List<int> theList,
                Random rnd)
            {
                List<int> newList = new List<int>(theList);
                for (int i = theList.Count-1; i > 0; --i)
                {
                    int r = rnd.Next(i+1);
                    int temp = newList[r];
                    newList[r] = newList[i];
                    newList[i] = temp;
                }
                return newList;
            }
        }
    }

That’s a whole easier to read because you don’t have to parse the full type name to find the part that’s important. Although it might not make much of a difference in this small program, it makes a huge difference when you’re looking at code that uses a lot of objects, all of whose type names begin with MyCompany.MyApplication.MySubsystem.MyArea.

The use of using is ubiquitous in C# code. Every significant Microsoft example uses it. Every bit of open source code I’ve ever seen uses it. Every C# project I’ve ever worked on uses it. I wouldn’t think of not using it. Nearly every C# programmer I’ve ever met, traded email with, or seen post on StackOverflow and other programming forums uses it. Even the very few who don’t generally use it, do bend the rules, usually when LINQ is involved, and for extension methods in general.

I find it curious that extension methods are excepted from this rule. I’ve seen extension methods cause a whole lot more programmer confusion than the using directive ever has. Eliminating most in-house created extension methods would actually improve the code I’ve seen in most C# development shops.

The arguments against employing the using directive mostly boil down to, “but I can’t look at a code snippet and know immediately what the fully qualified name is.” And I agree: somebody who is unfamiliar with the C# base class library or with the libraries being used in the current project will not have the context. But it’s pretty unlikely that a company will hire an inexperienced C# programmer for a mid-level job, and anybody the company hires will be unfamiliar with the project’s class layout. In either case, a new guy might find the full qualification useful for a week or two. After that, he’s going to be annoyed by all the extra typing, and having to wade through noise in order to find what he’s looking for.

As with having friends named Joe Green and Joe Smith, there is potential for ambiguity if you have identically named classes in separate namespaces. For example, you might have an Employee class in your business layer and an Employee class in your persistence layer. But if your code is written rationally, there will be very few source files in which you refer to both. And in those, you can either revert to fully-qualified type names, or you can use namespace aliases:

    using BusinessEmployee = MyCompany.MyProject.BusinessLogic.Employee;
    using PersistenceEmployee = MyCompany.MyProject.Persistence.Employee;

Neither is perfect, but either one is preferable to mandating full type name specification in the entire project.

The code example still has unnecessary redundancy in it that impedes understanding. Consider this declaration:

    List<int> myList = new List<int>();

That’s like saying, “This variable called ‘myList’ is a list of integers, and I’m going to initialize it as an empty list of integers.” You can say the same thing more succinctly:

    var myList = new List<int>();

That eliminates the redundancy without reducing understanding.

There is some minor debate in the community about using var (i.e. implicit typing) in other situations, such as:

    var newList = RandomizeList(myList, rnd);

Here, it’s not plainly obvious what newList is, because we don’t know what RandomizeList returns. The compiler knows, of course, so the code isn’t ambiguous, but we mere humans can’t see it immediately. But if you’re using Visual Studio or any other modern IDE, you can hover your mouse over the RandomizeList, and a tooltip will appear, showing you the return type. And if you’re not using a modern IDE to write your C# code, you have a whole host of other problems that are way more pressing than whether or not a quick glance at the code will reveal a function’s return type.

I’ve heard people say, “I use var whenever the type is obvious, or when it’s necessary.” The “necessary” part is a smokescreen. What they really mean is, “whenever I call a LINQ method.” That is:

    var oddNumbers = myList.Select(i => (i%2) != 0);

The truth is, they could easily have written:

    IEnumerable<int> oddNumbers = . . .

The only time var is absolutely necessary is when you’re working with anonymous types. For example, this code that creates a type that contains the index and the value:

    var oddNumbers = myList.Select((i, val) => new {Index = i, Value = val});

I used to be in the “only with LINQ” camp, by the way. But after a while I realized that most of the time the return type was perfectly obvious from how the result was used, and in the few times it wasn’t, a quick mouse hover revealed it. I’m now firmly in the “use implicit typing wherever it’s allowed” camp, and my coding has improved as a result. With the occasional exception of code snippets taken out of context, I’ve never encountered a case in which using type inference made code harder to understand.

If you find yourself working in one of the hopefully very few shops that restricts the use of these features, you should actively encourage debate and attempt to change the policy.

If you’re one of the hopefully very few people attempting to enforce such a policy (and I say “attempting” because I’ve yet to see such a policy successfully enforced), you should re-examine your reasoning. I think you’ll find that the improvements in code quality and programmer effectiveness that result from the use of these features far outweigh the rare minor inconveniences you encounter.

How to waste a developer’s time

A company I won’t name recently instituted a policy that has their two senior developers spending a few hours per week–half hour to an hour every day–examining code pushed to the source repository by other programmers. At first I thought it was a good idea, if a bit excessive. Then I learned what they’re concentrating on.

Would you believe they’re concentrating on things like indentation, naming conventions, and other such mostly lexical constructs? That’s right, they’re paying senior developers to spend something like 10% of their time doing a job that can be done more accurately, more completely, and much faster by an inexpensive tool that is triggered with every check-in.

And they wonder why they can’t meet ship dates.

Style issues are important, but you don’t pay your best developers to play StyleCop. If they’re going to review others’ code, they should be concentrating on system architecture issues, correctness, testability, maintainability, critical performance issues, and a whole host of high-level issues that it takes actual human intelligence to evaluate.

Having your best developers spend time acting like mindless automatons is not only a huge waste of money and talent, it’s almost guaranteed to cost you a senior developer or two. I hope, anyway. Forcing any developer to play static analyzer on a regular basis is one of the fastest ways to crush his spirit. And any developer who’s worth the money you’re paying him will be working for your competitor in no time flat rather than waste his time doing monkey work.

The drawbacks of having your senior developers spend their time examining code for style issues:

  • They can’t do as good a job as StyleCop and other tools.
  • They can’t do it as fast as StyleCop and other tools.
  • They can’t do it on every check-in.
  • There are much more important things for them to spend their time on.
  • They hate doing it.
  • They will find somewhere else to work. Some place that values their knowledge and experience, and gives them interesting problems to solve.

Benefits of having your senior developers spend their time examining code for style issues:

  • ??

Jim’s building furniture?

I might have mentioned a while back that Debra bought me a one-year membership to TechShop for Christmas last year. She also gave me a gift certificate for five classes. The way TechShop works, a member has to take a class covering Safety and Basic Use before using most of the equipment. The five classes I’ve taken so far are Wood Shop SBU (covers table saw, bandsaw, sander, drill press), Jointer, Planer, and Router, Wood Lathe, Laser Cutter, and Sandblasting and Powder coating.

Since January I’ve spent lots of time at TechShop, mostly cutting up logs for carving wood. I have a bandsaw at home, but it can’t cut material thicker than six inches, and its throat depth is something less than twelve inches. The bandsaw at TechShop can cut a twelve-inch-thick log, and has a much deeper throat. I can cut bigger stuff on their bandsaw.

In late August, I saw that my neighbor who owns a handyman business had a trailer full of wood. It turns out that he had removed an old cedar fence and deck for a client, and was going to haul the wood off to the dump. I spent six hours pulling nails, and drove home with a truckload of reclaimed lumber. Then I got busy making things.

truckload

I had seen an American flag made from old fencing, and wanted to make one. Given that I now had plenty of old fence to play with, I cut a bunch of one-inch strips, painted them up, and glued them back together. The result is this flag, which is 13 inches tall and 25 inches wide, matching the official width to height ratio of 1.9.

flag1

I’ve since made two others that size, and one smaller. Then I stepped up to 1.5 inch strips to make a flag that’s 19.5″ x 37, and got the crazy idea that it’d look better in a coffee table than it would hanging on the wall. So, blissfully ignorant of what I was getting into, I set about building a coffee table.

The only thing I’d built from scratch before was that oval table, and it got covered with a tablecloth. Besides, all I did was slightly modify a work table plan that I found online. I designed this table myself, and set the goal of making from 100% reclaimed wood. I’ll save the step-by-step instructions for another time. Suffice it to say that it took me an absurdly long time and a lot of mistakes to finish constructing it. But the result is, I think, very nice.

flagTable_t

The table is 17.5 inches tall, and measures approximately 42″ x 26″. The only wood on it that’s not reclaimed is the eight dowels used to hold the apron together.

Mind you, the table is constructed, but it’s not finished. The flag is recessed about 1/8 inch below the border. I’m going to fill that space with epoxy resin. Most likely, the resin will also flow over the border to protect it. I’ll use an oil finish, probably something like tung oil.

I couldn’t build just one table, though. So shortly after I finished that one I made a Texas state flag. Last night I completed construction of my Texas table, which measures about 42″ x 30″, and is also 17.5 inches tall. It’s wider than the other table due to the Texas flag’s width-to-height ratio of 3 to 2. So a 36 inch wide flag is 24 inches tall.

texasTable_t

This table, too, has the flag recessed, and the space will be filled with epoxy resin.

The construction of the Texas table is a little different than the first one. Most importantly to me, I constructed the apron with finger joints rather than using dowels at the corners. That allows me to say that the table is 100% reclaimed wood. Plus, the finger joints are easier. Dowels are a pain in the neck.

I’m going to make at least one more of each of these tables, probably using the Texas table design. But before I do that I need to work on a project for Debra. That one’s going to be especially fun because I’ll get to play with the ShopBot. Once I take the class, that is.

 

Categories

A sample text widget

Etiam pulvinar consectetur dolor sed malesuada. Ut convallis euismod dolor nec pretium. Nunc ut tristique massa.

Nam sodales mi vitae dolor ullamcorper et vulputate enim accumsan. Morbi orci magna, tincidunt vitae molestie nec, molestie at mi. Nulla nulla lorem, suscipit in posuere in, interdum non magna.