Tuesday, January 5, 2010

Terse and readable code

I found a new blog today while searching for the answer to a tech question.  I always love finding blogs this way.  When a real IT person is able to share the solutions to their real problems in real English - well that's just a gem I can't resist.  So I subscribed to his RSS feed, and noticed a recent post about adding an extension method to the DateTime class in .NET so that you can easily calculate Age.

Debate about whether age calculation is an appropriate use of an extension method aside, this is the code that was posted:

public static int Age(this DateTime dob, DateTime fromDate)
   int dobYear = dob.Year;
   int fromDateYear = fromDate.Year;
   int age = fromDate.Year - dob.Year;
   //your birthdate month has not occurred yet
   if ((fromDate.Month - dob.Month) < 0)
       return age == 0 ? age : age - 1;
   //the day of the month of your birthday has not occurred
   if ((fromDate.Day - dob.Day) < 0)
       return  age == 0 ? age : age - 1;
   return age;

public static int AgeFromNow(this DateTime dob)
   return dob.Age(DateTime.Now);

Now, it may be a bit unfair to pick on this person's code - especially when I think the blogger in question has a really great blog.  But when you name your blog "Awesome Code" (not the real name, but that's the gist), and you post code like this, it seems only right to have some level of scrutiny of the code you post.  Not sure why dobYear and fromDateYear were even declared only to never be used again, but even if you take out those two lines this code is much more verbose than it needs to be.

I went to my codebase from work and pulled out our Age calculation method.  Here it is: 

Public Shared Function GetAge(ByVal dob As DateTime) As Integer
   Return GetAge(dob, DateTime.Now)
End Function

Public Shared Function GetAge(ByVal dob As DateTime, ByVal dt As DateTime) As Integer
   If dt.Date < dob.Date Then Return 0
   Dim factor = If(dt.DayOfYear < dob.DayOfYear, 1, 0)
   Return dt.Year - dob.Year - factor
End Function

Even though VB is more verbose by nature, this code is still much nicer.  As long as the code stays readable, I have a lot of respect for a terse, to-the-point solution to simple problems.  It's like Larry Wall says - the easy things should be easy, and the hard things possible.