Archive

Posts Tagged ‘c-sharp’

Remedial Scala: Emulating C# Extension Methods

January 17th, 2009 4 comments

I admit that, as a Java programmer, I’ve been jealous of C#’s extension methods for a while. Java’s getting pretty long in the tooth. While C# is adding lots of cool new features, Sun doesn’t have the balls to even add closures despite three working implementations to choose from.  I get bimonthly reports from a former co-worker and C# aficionado of this or that cool feature that Java will never have.  He loves to rub it in.

I know that extension methods are just syntactic sugar and any Lisp adherent will tell you they’re really just a poor man’s version of generic functions.  But I want them nonetheless.

So, forget about Java. I’m pleased to say that in Scala it is easy to emulate extension methods. Here’s Microsoft’s example code in C#:

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' },
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }
}

this just adds a WordCount method to the built in string class. Here’s the equivalent code in Scala, with a main method for good measure:

object Main {

  implicit def stringToWordCounter(s : String) = {
    new {
      def wordCounts : Int = {
        s.split(Array(' ', '.', '?')).map(_ trim).filter(! _.isEmpty).size
      }
    }
  }

  def main(args: Array[String]) {
    println("Hello Extension Methods".wordCounts)
  }

}

This makes use of Scala’s support for implicit conversions. If a method is called on an object that doesn’t exist on that object’s base type, the compiler searches for an implicit method (stringToWordCounter in this case) that converts to a type that does have that method. stringToWordCounter converts implicitly to a anonymous class that just happens to have a wordCount method. Cool. Note that the returned type can have any number of methods and may also implement traits (interfaces).

One thing I don’t know about is performance. Implicit conversions mean constructing a new intermediary object to call the method on. Maybe the compiler is smart? Anyway, this is remedial Scala, so I’ll worry about that later.

Also of note in this example is how much nicer the code to split, trim, and filter the input string is. I’m assuming there’s some other, more functional way to do this in C# without resorting to the long-winded StringSplitOptions.RemoveEmptyEntries flag.

That’s it for today’s installment of Remedial Scala. See you next time.

Categories: scala Tags: , ,