Saturday, June 28, 2008
Pretty code in blogs
I love Blogger. I have been using it for about 2 years in my personal blog and it has done me really well. When I decided to start up a tech blog, I figured that Blogger would work great for that as well. Unfortunately, in my last two posts, I had a bear of a time getting my code to format. Once I thought I had it, Blogger would re-format my code enough that my formatting got all screwed up again.
I had gotten so frustrated, I was almost ready to switch blog software all together. Then I came across this Google Code project called SyntaxHighlighter. It is the tool I am using to make the source code on my blog look all pretty and shiny. It took me a bit of work to get it all set up, but this blog post helped me along.
Now, I can't say that I LOVE the usage here... I still need to bust into HTML in order to add a <pre name="code" class="c-sharp"> block, but it is a heck of a lot easier than what I had before. Thank you SyntaxHighlighter, you saved my day.
Thursday, June 26, 2008
Generic constraints for value types
I came across an oddity in the C# language the other day. I was trying to create a generic method that returned a nullable value. A simple example of this:
public T? GetNullable<T>(int index)
{
if(index < 0)
return null;
return default(T);
}
This will result in a compiler error:
Error 1 The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable<T>'
This is a cryptic error that means that I need to put a constraint on my method to restrict it to a value type. In C#, this is done with the 'struct' keyword:
public T? GetNullable<T>(int index) where T : struct
This seems really odd to me. If someone were to read the interface for this class, it is not at all clear that I can send an int, bool double, etc into this method.
It turns out that T? and System.Nullable<T> compile into the same IL and the interface for System.Nullable<T> also has a constraint on 'struct'. So, as odd as it is, we need to consider the 'struct' constraint to really mean any value type.
Just a little bit later, I created a utility method to convert a string to an enum. The code is really straight forward:
public T GetEnum<T>(string enumValue)
{
return (T)Enum.Parse(typeof (T), enumValue);
}
Because this method is only designed to be used for enums, it would be great if I could add an enum constraint:
public T GetEnum<T>(string enumValue) where T : enum
This, unfortunately, is not valid. C# does, however, allow you to put a constraint with a base class. Since all enums are derived from System.Enum, I thought I could restrict using System.Enum:
public T GetEnum<T>(string enumValue) where T : System.Enum
Again, no dice. System.Enum is considered a "special class" and cannot be used as a constraint. So, again, I am stuck using the 'struct' constraint and again, I am left feeling like this is not quite right. With this constraint, it would be perfectly acceptable to to write the following:
GetEnum<int>("4");
Woof. I guess the only thing I can do now, is to add the following parameter check:
if(!typeof(T).IsEnum)
throw new ArgumentException("Type T Must be an Enum");
This is the best I can do, thought it is far from ideal. It gives me a runtime check, at least, even though I can't get a compile-time check.
It leaves me hoping that in C# 4.0, that we see some significant changes to generic constraints. It would be nice if we could at least have an Enum construct. In addition, it would be nice to use the 'value' keyword in constraints instead of 'struct'. It will only improve readability.
Tuesday, June 24, 2008
On Readability and Maintainability
In the last 6 weeks, I have been spending a lot of my time rearchitecting my software. Along with this comes a lot of refactoring. It gets me to thinking about readability and maintainability. I came across a situation where there were several methods with the same boilerplate code. I reduced this down to a single method that takes a delegate and each dependant method calls into the single method with an implementation of a filter. When it was all said and done, I had sacrificed readability for maintainability. Following is a contrived example that shows my dilema:
Before:
Notice how each of these methods has the same boilerplate code. They are already pretty straight-forward:
public ICollection<string> GetDataWithABC(IDataSource dataSource)
{
List<string> result = new List<string>();
using(IDataReader reader = dataSource.GetData("ABC"))
{
while(reader.Read())
{
string value = reader.GetString(0);
if(CheckAboutABC(value) && value.Contains("JUNK"))
result.Add(value);
}
}
return result;
}
public ICollection<string> GetDataWithDEF(IDataSource dataSource)
{
List<string> result = new List<string>();
using (IDataReader reader = dataSource.GetData("DEF"))
{
while (reader.Read())
{
string value = reader.GetString(0);
if (value.Contains("BLAH"))
result.Add(value);
}
}
return result;
}
public ICollection<string> GetDataWithXYZ(IDataSource dataSource)
{
List<string> result = new List<string>();
using (IDataReader reader = dataSource.GetData("XYZ"))
{
while (reader.Read())
{
string value = reader.GetString(0);
if (CheckAboutXYZ(value) && CheckSomethingElseXYZ(value))
result.Add(value);
}
}
return result;
}
1. Create a list to return
2. Get the data reader from the data source
3. While there is data, Get the data, filter it and add the values to the list
4. Return the list
I think this code is pretty readable. Of course, it is not maintainable. If IDataSource is changed, for example, to return an IEnumerable, then we have to change all three methods. In my example, there were more like 10 methods with the same boilerplate code.
The only real difference in any of these methods is the filter. Why not extract the boilerplate code into a single method and pass a delegate to do the filtering? The result looks like this:
After:
I love this approach. There is no duplication of code anymore. If something changes with the boilerplate code, it can be changed in one spot. I have saved lines of code and everything is more compact.
private delegate bool DataFilter(string value);
private static ICollection<string> GetDataWithFilter(IDataSource dataSource, DataFilter filter)
{
List result<string> = new List<string>();
using (IDataReader reader = dataSource.GetData("ABC"))
{
while (reader.Read())
{
string value = reader.GetString(0);
if (filter(value))
result.Add(value);
}
}
return result;
}
public ICollection<string> GetDataWithABC(IDataSource dataSource)
{
return GetDataWithFilter(dataSource, delegate(string value)
{
return CheckAboutABC(value) && value.Contains("JUNK");
});
}
public ICollection<string> GetDataWithDEF(IDataSource dataSource)
{
return GetDataWithFilter(dataSource, delegate(string value)
{
return value.Contains("BLAH");
});
}
public ICollection<string> GetDataWithXYZ(IDataSource dataSource)
{
return GetDataWithFilter(dataSource, delegate(string value)
{
return CheckAboutXYZ(value) && CheckSomethingElseXYZ(value);
});
}
Unfortunately, I think that the code has become less readable. First, it becomes difficult to discern what is going on there at first glance. The use of the inline delegate is a bit confusing and can trip up people who read this for the first time. Second, the double return is confusing. The inner return returns a bool where the method returns an ICollection. I have seen this trip up experienced developers who glance at the method. It is also more difficult to debug.
I could always strip the delegates out into separate methods, but I believe that is even more unreadable. Whats worse, is that we didn't really save many lines of code. Only 9 lines of code were saved. (more were saved in my real-world scenario)
So what is better? Readability or Maintainability?
A colleague whom I have a lot of respect for told me "Always go with readable". I guess, in this case, I have to disagree with him and go with Maintainability. Duplication of code, for me, is a real big no-no. Duplication 10 times is an even bigger no-no. In this case, I think the maintainability gain outweighs the readability loss. I will even argue that as you shorten the length of each individual method, the aggregated file becomes more readable as a whole.
As a side note, it turns out that in C# 3.0, you can use lambda functions to make it a bit more readable. Unfortunately, we aren't using 3.0 yet:
public ICollection<string> GetDataWithABC(IDataSource dataSource)
{
return GetDataWithFilter(dataSource, value => CheckAboutABC(value) && value.Contains("JUNK"));
}
Monday, June 23, 2008
Lansing Day of .NET
In one of my favorite tech blogs, Coding Horror, Jeff Atwood blogs about what it means to practice your profession. More specifically, he mentions that you can do your job without practicing your profession. That everyone drives every day, but most people are not professional drivers.
In his post, he brings up several things you can do to become more practiced as a developer. One of those things is "Write a blog". It seems he (who is a developer turned professional blogger) believes that what I have decided to do (write a blog) is worthwhile to my career. It helps me get past my fear that I am just doing this to feed my own ego... which it feels a bit like.
I believe that another thing that is important for practicing your career is going to conferences. On Saturday, I attended the "Day of .NET" in Lansing. I left feeling like I learned a TON! It was a great thing for me professionally.
One thing that I enjoyed about this conference was the fellow attendants. See, this conference was held on a Saturday. I can't say that I have gone to many Saturday conferences. I think they do this so people who can't get their bosses to let them go during the week can still go to this conference. The side affect is that the people who attend are the types of people who are truly interested in learning outside of work. The enthusiasm about the conference and the topics was quite a bit stronger than I have ever seen at something like this.
I am starting to understand that this community is not terribly large. I recognized many of the people there from the Ann Arbor .NET Users Group, blogs and podcasts. Many of these people are people that I follow on Twitter because I have found what they have to say interesting through one of the previously mentioned venues. Although most of these people do not know me, I find that their views resonate with what I believe about software.
While at the conference, I sat through several talks. The ones I found most interesting were the Castle Project talks. It is interesting how the technology has progressed (my analysis):
First, there was ruby on rails. They did some really neat things. Then came Java with Hibernate, Spring, etc to try to do what rails did. Then came the Castle Project for .NET, with ActiveRecord (on top of NHibernate), Windsor and Monorails. From there, Microsoft lifted their heads and realized "Hey! We should do this". From there, Entity Framework and ASP MVC were born.
Those ruby folks were really on to something!
Anyways, the conference was good and I learned a lot about Entity Framework, Castle ActiveRecord, Castle Windsor and ASP MVC. I expect to play a lot with these technologies over the next few months, and continue practicing my craft.
Saturday, June 21, 2008
The start of a new blog
Why am I doing this? Another blog? Another blog about software? Just another programmer who thinks that someone might care what he has to say? I don't know. I guess I am doing it to create more of an online presence... although if you "google" my name, you will find countless usenet conversations about everything from "SSH Tunneling" to blueberry jam. Searching for my alter-ego, Bilzmoude, will come up with a similar mish-mash of topics such as beer and MythTV. My presence is small, but it is there.
So why a technical blog? Hasn't everyone already written everything I have to say? What is the point? Is this realling going to increase my "web footprint"?
The point, I suppose, is to collect my thoughts about programming. I want it to capture what I am thinking in the moment. As my views change, I would like to be able to look back and see HOW they have changed. For instance, there was a time when I strongly believed that code without comments was bad code. I know believe the exact opposite. Likewise, I used to believe all functions should have a single exit point and have since changed my mind on that too. I know that I am growing as a developer because I am always changing my mind. As long as I am doing this, I know that I am still learning.
I am also trying to learn to write better. Throughout high school and college, I took the common engineering attitude that writing wasn't my thing... programming was. I regret that attitude now that I am over 30 and my writing reads like a high-schooler. If I write more in my blog, will my writing get better? I hope so.
There are several things I want to write about, though I can't promise how often I will actually write. I have had several blogs in the past (and I am currently maintaining a family blog with my wife) but historically, I have not written very frequently. If history is an indicator, this blog will be similar.