Archive for the ‘c#’ Category

Modifying large codebases in dynamic and static languages

Saturday, April 5th, 2008

I’ve been wondering recently about dynamic languages, and static languages, and the relative benefits.

I’m struggling with this question because I write C#3 by day, and am learning python in the evenings. I’m only writing small python scripts at the moment and I’d like to write larger pieces, but I’m concerned about how easy it’ll be to make certain types of change.

For example. You’ve got 100,000 lines of code. You also have a logging function that’s looks like this;

void Log(string message)

And it’s called about 200 times in your code. You decide you need a severity; so you change the signature to

void Log(string message, LoggingSeverity severity) { .. }

Now, how long does it take to find all the calls to the Log() function that need to be updated? Under C#, about ten seconds. Once every call has been fixed, the code is almost certain to work correctly.

Consider, on the other hand, the python function

def log(message):
    ...

What happens if you change the signature to

def log(message, severity):
    ...

There is no way to tell where the log message is called. You’ve just introduced 200 bugs.

It’s made even worse by duck typing; maybe you have two loggers — a deployment logger which writes to a database, and a test logger which writes to stdout. You update the database logger so it has severity. Your tests continue to pass, but your deployed system will fail.

So it seems to me that static languages give you much more power to make changes to large codebases. I’d love to know if, and where, the mistakes are in my thinking.

Object-oriented vs class-oriented programming

Sunday, January 13th, 2008

In his well-reasoned blog post, chuck hoffman argues that what are normally called object-oriented programming languages should probably more rightly be called class-oriented languages. The distinction hopefully becomes clear when you consider this example.

You are modelling people, and you want to create a person type. You should be able to strike up a conversation, so we want a ‘greet’ method for each. Our people (Alice, Bert, Charlie, and Dennis) all respond differently;

  • Alice responds to a greeting with “Hi!”, or a surly “what!?” if she hasn’t had her morning coffee.
  • Bert responds with either “don’t bother me, I’m walking Spot” or “what can I do for you?”, depending on whether he is walking his dog.
  • Charlie responds with either “good morning”, “good afternoon”, or “good evening”, depending on the time of day.
  • Dennis responds with “Hello, world!”

Now, in C#, that’s really tricky. Each person uses a different function to answer your greeting. But in C#, the Person class can only have one implementation. You could munge them all together;

class Person
{
  string Greet()
  {
    if (isBert && isWalkingSpot) {return "don't bother me, I'm walking Spot"; }
    else if (isAlice && !hasHadCoffee) { return "what!?"; }
    ... etc
  }
}

But that is monstrous. You could create subclasses;

class Dennis: Person
{
  public override string Greet() { return "Hello, World!"; } 
}

But this isn’t a class of thing; Dennis is singular. There’s not a whole class of Dennises, just a single solitary one.

What you really want to be able to do is something like this; (excuse the made-up syntax)

Person Alice = new Person();
Alice.HasCoffee = false;
Alice.Greet = { (HasCoffee ? "Hi!" : "what!?") }

Person Dennis = new Person();
Dennis.Greet = { "Hello, World" };

That’s what an object-oriented, rather than a class-oriented, version of c# might look like.

C# Coding; Missing Functions on IEnumerable

Thursday, January 3rd, 2008

Me old mucker Spencer pointed out today that C# 3’s newly-refurbished IEnumerable<T> class lacks some basic features. Specifically, it lacks equivalents for the classic Map, Filter, and Reduce functions seen in functional languages. The first two are familiar as List<T>.ConvertAll, and List<T>.FindAll. The third isn’t so familiar, but is still very useful. I’ve also thrown in an implementation of ForEach for free.

Ben Hall points out that it’s possible to extend the class, but I wanted to get a full, commented implementation of the three functions. Feel free to use this code in your own work.

So, here they are;

IEnumerableExtras

public static class IEnumerableExtras
{
    /// <summary>
    /// Do 'action' to every item in the list.
    /// </summary>
    /// <typeparam name="T">The source type</typeparam>
    /// <param name="list">the IEnum</param>
    /// <param name="action">the action to perform.</param>
    public static void ForEach<T>
        (this IEnumerable<T> list, Action<T> action)
    {
        foreach (T item in list) { action(item); }
    }

    /// <summary>
    /// Convert every item in the list using the converter
    /// function
    /// </summary>
    /// <typeparam name="T">The source type</typeparam>
    /// <typeparam name="U">The destination type</typeparam>
    /// <param name="list">the list to convert</param>
    /// <param name="converter">a function to convert 
    /// one item to another.</param>
    /// <returns>all items in the list converted by 
    /// the converter function.</returns>
    public static IEnumerable<U> Map<T, U>
        (this IEnumerable<T> list, Converter<T, U> converter)
    {
        foreach (T item in list) 
        {
          yield return converter(item); 
        }
    }

    /// <summary>
    /// Returns a new enumerator containing only those 
    /// elements which return true from 'condition'.
    /// </summary>
    /// <typeparam name="T">The source type</typeparam>
    /// <param name="list">the list to filter</param>
    /// <param name="condition">the 'keep in' condition</param>
    /// <returns>the items for which condition(item) 
    /// is true</returns>
    public static IEnumerable<T> Filter<T>
        (this IEnumerable<T> list, Predicate<T> condition)
    {
        foreach (T item in list) 
        {
          if (condition(item))
          {
            yield return item; 
          }
        }
    }

    /// <summary>
    /// Reduces a list of items to a single item; can be 
    /// used to, say, sum a list of integers, or 
    /// concatenate a number of strings, or find the 
    /// maximum value in a collection.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="list"></param>
    /// <param name="reducer"></param>
    /// <returns></returns>
    public static T Reduce<T>
        (this IEnumerable<T> list, Func<T, T, T> reducer)
    {
        IEnumerator<T> enumerator = list.GetEnumerator();
        if (enumerator.MoveNext())
        {
            // we have some items; start combining them together.
            T aggregator = enumerator.Current;
            while (enumerator.MoveNext())
            {
                aggregator = reducer(aggregator, 
                    enumerator.Current);
            }
            return aggregator;
        }
        else
        {
            // there was nothing in the list; return default.
            return default(T);
        }          
    }
}

And here’s an example program;

static void Main(string[] args)
{
  IEnumerable<double?> maybeDoubles = 
      new List<double?> {1, 2, null, 3, 4, null, null, null};

  // remove all the empty values: <double?>[1,2,3,4]
  IEnumerable<double?> noNulls = maybeDoubles.Filter(x => x.HasValue);

  // convert Nullable to non-nullable: ><double>[1,2,3,4]
  IEnumerable<double> notNullable = noNulls.Map(x => x.Value);

  // convert to strings so we can display them. <string>["1", "2", "3", "4"]
  IEnumerable<string> stringVersions = notNullable.Map(x=>x.ToString());

  // join the strings together with commas “1, 2, 3, 4″
  string displayString = stringVersions.Reduce( (s1, s2) => s1 + “, ” + s2); 

  // show us the result; 
  Console.WriteLine(displayString);
  Console.ReadLine();
}

So there you go. Enjoy.