Home > scala > Remedial Scala: Emulating C# Extension Methods

Remedial Scala: Emulating C# Extension Methods

January 17th, 2009 Leave a comment Go to 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: , ,
  1. January 21st, 2009 at 03:27 | #1

    Calls to wordCounts will use reflection (as that uses structural typing). It’s better to create a named type containing wordCounts:

    implicit def stringToWordCounter(s: String) = WordCounter(s)
    case class WordCounter(s: String) {
    def wordCounts…
    }

    Yes, it’s more repetitive, but it’s faster. C#’s extension methods have no runtime overhead, are simpler to write and much less flexible.

  2. dave
    January 21st, 2009 at 07:42 | #2

    Thanks for the tip. I originally wrote WordCounter as a separate class, but changed it when I found this less verbose version. I wouldn’t have guessed that that “anonymous” type would result in reflection. Do you think a case like this is an instance of a compiler that just isn’t smart enough yet, or is it by design? If Scala were more widely adopted, I’d really worry about performance hits like this being hidden in the concision of the language. My software is already usually really slow :)

  3. January 22nd, 2009 at 15:15 | #3

    Hi,

    Interesting article. I just blogged about the problems associated with the static binding of extension methods. (http://ruben.3click.be/blog/extension-methods-silent-static-slaves)

    I’m not familiar with Scala, but the code of the stringToWords function makes it look like the binding happens at runtime, as I don’t see a “static” keyword. Is that correct? If so, it would mean that this technique is actually a lot better then extension methods.

  4. January 22nd, 2009 at 17:51 | #4

    Thanks. I also enjoyed your article. For some reason the line “Try to ignore the static, people!” made me laugh. Anyway, as the title suggests, I’m still learning Scala, but my impression is that Scala’s implicit conversions, like extension methods, are bound at compile time (Scala doesn’t have a static keyword). However, the conversion method may return an object of any type it wishes and the method is actually called on that returned object. I think this is why Ricky says that C#’s extension methods are less flexible above. I’m still learning. This post seems to give an example of more powerful usage, but it’s assumes a pretty good knowledge of Scala.

    Thanks again for the comment.

  1. No trackbacks yet.