Friday, November 11, 2011

On Implicit Typing in C#

I pulled out a copy of ReSharper after not having used it for a little while and turned it on my code. It's still a great tool but it kept bugging me about something:

"Use implicitly typed local variable declaration."

I was bewildered for a moment because I thought that sounded like it wanted me to use a var instead of a type. After some research, I was more bewildered because I found out it truly was.

My first landing was this. The writer references a post by Ilya Ryzhenkov at JetBrains that defends it. I also read Microsoft's unopinionated write-up of untyped local variables. The short version is that when you declare a local variable inside a method, you use an untyped declaration -- var, instead of int, or whatever other type it is -- and let the compiler figure it out.

From what I can see of the argument, it's for two reasons:
  • this is supposedly easier to read, and,
  • if the type changes, the code will function.
For the first postulate, I don't understand the argument. In the trivial case, var is no less difficult to read than int. If your type is Dictionary<Group, Member>, using var shields you from this. I couldn't find any justification for this and I can't say I agree.

There's a related argument as well, that if you use an untyped variable, it teaches you to correctly name your variables. On this, I'd flat-out disagree. We switched away from Pascal-naming a long time ago, for a reason. Further, good practices teach single-responsibility methods, which means your method body should be short. Short methods should fit on one screen and the reader should always be able to see the declaration throughout the entire method. Since the beginning of C, we've been using i as the primary index in a for loop, because it works well and increases readability. If a programmer lacks discipline, either in variable naming or in writing lengthy methods, they should correct this issue. The compiler should not enforce style.

As for changing types, whatever happened to programming to an interface? When the interfaces changes, the code that consumes it needs to change as well. This is a highly useful feature, not a problem. If a method I use from an API gets a signature change, I want the compiler to show me everywhere that my code needs to change. When I wrote the code, I expected a particular return type and my code depends on that. Changing the return type is likely to make my code do a different and unexpected thing. There are times I write code that intentionally deals with multiple possible return types and C# has an extensive set of features for exactly this case, from abstraction and polymorphism, to delegates and reflection. All are written so that type safety is preserved, from the reader's point of view. I'm not programming to make the compiler happy and readability -- therefore maintainability -- is usually my second or third highest concern when coding.

This takes me to a final point, that there are implicitly-typed languages out there. Until the var keyword was introduced, C# was not one of these languages. I don't think there is a coincidence that var was introduced with LINQ and I still explicitly type my LINQ statements most of the time.

There are times when I don't want explicit typing, like when I'm writing a script to sort my photo collection. When they come along, I use an implicitly-typed language and I don't think it's strange that this is almost always scripting. When it's not, there are plenty of options like F#, Ruby, Perl and VBScript, to mention just a few. For enterprise applications, my goal isn't just to get software out the door, but rather to deliver something that the next person will be able to maintain and add to, or myself but two years later when I've forgotten why I wrote it that way.

No comments:

Post a Comment