Thursday, January 29, 2009

Poor man's string interpolation in C#

String interpolation is a nice feature in some languages like PHP, Ruby, Perl, Boo and Nemerle that makes string formatting very easy. Its absence in C# causes language envy, feature requests and hacks like these and the one presented here.

The way I see it, string interpolation is just applying a string template. So we could use a light, simple templating engine like NVelocity. That covers the templating problem.

The other problem is the gathering of the values to be injected in the template. This is pretty much unsolvable in C# because the compiler doesn't store local variable names in the assembly. Of the .NET languages I mentioned before, Boo and Nemerle, Boo just has this feature built into the compiler. If you write this in Boo:

product = "keyboard"
price = 123
text = "The ${product} costs ${price}"
print text

It compiles to this:

private static void Main(string[] argv) {
    string product = "keyboard";
    int price = 0x7b;
    Console.WriteLine(new StringBuilder("The ").Append(product).Append(" costs ").Append(price).ToString());
}

Nemerle solves string interpolation by using its strong macro capabilities.

C# has none of these features, so one way or another we have to manually define the parameters. So it's just a matter of finding the easiest way to define named parameters. How about this one?

[Test]
public void Formatting() {
    var product = "keyboard";
    var price = 123.55m;
    var result = "The $product costs $price.ToString('C')".Fill(new { product, price });
    Assert.AreEqual("The keyboard costs $123.55", result);
}

I guess that's about as close as I can get. It's not the same as having it supported by the language, but it's certainly prettier that String.Format()...

Source code is here.

Sunday, January 25, 2009

Simple dependency injection container with CommonServiceLocator

When I started developing SolrNet, one of my goals was to have a DI-friendly library but without taking a direct dependency on any specific container. I wanted to enable both IoC and non-IoC users to use the library with equal ease. So, for example, non-IoC consumers would code like this:

var solr = new SolrServer<Document>(ConfigurationManager.AppSettings["solrURL"]);

while IoC users would write (Windsor sample):

container.Register(Component.For<ISolrServer<Document>>()
	.ImplementedBy<SolrServer<Document>>()
	.Parameters(Parameter.ForKey("serverURL").Eq(ConfigurationManager.AppSettings["solrURL"]))); 

and then inject ISolrServer<Document> where they needed it.

But SolrServer itself had a number of dependent components. At first, this wasn't a problem, this number of components was low and component composition was shallow and simple. But as I added features to the library, there were more and more components, interacting in more complex ways. Since I wanted to keep the possibility of writing "new SolrServer...", every component was responsible for instantiating its own dependencies. Soon, I had component instances duplicated everywhere. Dependencies were not clear because I had "shortcut" constructors for each component. In a word, a mess.

It was time to refactor, make dependencies clear and explicit, and introduce a container to manage dependencies. But I didn't want to depend on any specific container! So I took a look at CommonServiceLocator, which is an abstraction over IoC containers. Just what I needed! Except for one little thing: it's a read-only abstraction, that is, it provides an interface to get things out of the container, but no methods to put things in the container. So it's up to the consumer of the library to appropriately register the library's components. This is stated in the docs:

Libraries should not configure the container
As a library or framework author, understand that you should not be putting anything into the container - that's the job of your caller. Allow the application writers to choose whatever container they want. You need to document what services you need registered, and if you're using the ServiceLocation.Current ambient container.

Well... I just don't agree with that. Consumers shouldn't have to know about the library's internal components lifestyles and dependencies. That's why complex stuff with many components are usually packaged into facilities (Windsor) or modules (Ninject, Autofac). But if I used a facility or module I'd be again depending on a single container!

Actually, there are very valid reasons why the CommonServiceLocator doesn't include Register(). Like the name says, it's a locator (read-only) abstraction, not a factory (creation) abstraction. Each container/factory has unique semantics for registering and creating components, different ways to handle lifestyles, disposable components, registering dependencies, and so on. More on this in this discussion between Hammett and Ayende.

But it still wasn't good enough for me, so the only way out was to write my own simple container on top of IServiceLocator. Based on this article from Ayende, I started with the following interface:

public interface IContainer : IServiceLocator {
    /// <summary>
    /// Adds a component implementing <typeparamref name="T"/>
    /// Component key is <typeparamref name="T"/>'s <see cref="Type.FullName"/>
    /// </summary>
    /// <typeparam name="T">Service type</typeparam>
    /// <param name="factory">Component factory method</param>
    void Register<T>(Converter<IContainer,T> factory);

    /// <summary>
    /// Adds a component implementing <typeparamref name="T"/> with the specified key
    /// </summary>
    /// <typeparam name="T">Service type</typeparam>
    /// <param name="factory">Component factory method</param>
    /// <param name="key">Component key</param>
    void Register<T>(string key, Converter<IContainer,T> factory);
}

Implementing this interface, I could register transient components:

[Test]
public void Transient() {
    var container = new Container();
    container.Register<IService>(c => new ServiceImpl());
    var inst1 = container.GetInstance<IService>();
    var inst2 = container.GetInstance<IService>();
    Assert.AreNotSame(inst1, inst2);
}

Also singletons:

[Test]
public void Singleton() {
    var container = new Container();
    var inst = new ServiceImpl();
    container.Register<IService>(c => inst);
    var inst1 = container.GetInstance<IService>();
    var inst2 = container.GetInstance<IService>();
    Assert.AreSame(inst, inst1);
    Assert.AreSame(inst, inst2);
}

Being such a simple container, injection is less declarative than in real containers:

[Test]
public void Injection() {
    var container = new Container();
    container.Register(c => new AnotherService(c.GetInstance<IService>()));
    var inst = new ServiceImpl();
    container.Register<IService>(c => inst);
    var svc = container.GetInstance<AnotherService>();
    Assert.AreSame(inst, svc.Svc);
}

And that's it for the basic container. Later I added component removal for easier testing and I also experimented with per-thread and per-HttpContext lifestyles just for fun, but I didn't really test them. Check out the full tests if you're interested.

Armed with this little container, I was able to clean up my dependencies and hide the internal components to non-IoC consumers while also allowing for other containers to be used, thanks to CommonServiceLocator. More on this when I release the next version of SolrNet.

Source code:

Monday, January 19, 2009

Generalized curry in F#

When coding in F#, you really get used to the automatic currying the language provides. It feels just natural. However, F# lives within the .NET world, so sooner or later, you have to call some function from the BCL or another assembly you have coded in C#. Problem is, F# maps the method parameters as tuples, so they are uncurried. Let's take for example String.Compare(string,string). When coding in F#, its signature is (string * string) -> int so you have to call it just like you would in C#:

String.Compare("something", "something else")

If it were curried, its signature would be string -> string -> int, so you could call it like this:

String.Compare "something" "something else"

This little difference can get quite annoying. It feels like an "exceptional" call when you have to put the parens.

Of course, it's not arbitrary that F# doesn't automatically curry every function in the framework. For example, curried functions are actually implemented with FastFuncs, so String.Compare would have to be wrapped in a function that took a string and returned a FastFunc<string, int> closure which in turn calls the actual String.Compare. No such thing as a free lunch :-)

So I set out to either find or develop a way to curry any function.

Looking for inspiration in other languages, I found that generalized currying can be done fairly easily in dynamic languages like LISP, Scheme, Javascript, Ruby. As an aside note, I was quite surprised that Matz treated currying in Ruby as an "easter egg for functional programming kids". (?)

In statically typed languages it's more complicated. The difference seems to be that arity isn't a concept as strong in dynamic languages as it is in statically typed ones. In C#, although not a mainly functional language, generalized currying can be implemented by creating different overloads of a curry function, one for each arity. Haskell has its own set of solutions, which I'll someday understand but not today :-)

I asked on hubFS, it seems that there isn't anything standard yet for F#. So I tried to use method overloading to overcome the arity problem. The result is this boring code, similar to Dustin's solution:

type FP =
    static member curry2 (f:_*_ -> _) = 
        fun a b -> f (a,b)

    [<OverloadID("curry2")>]
    static member curry (f:_*_ -> _) = 
        FP.curry2 f

    static member curry3 (f:_*_*_ -> _) = 
        fun a b c -> f (a,b,c)
        
    [<OverloadID("curry3")>]
    static member curry (f:_*_*_ -> _) = 
        FP.curry3 f
        
    static member curry4 (f:_*_*_*_ -> _) = 
        fun a b c d -> f (a,b,c,d)

    [<OverloadID("curry4")>]
    static member curry (f:_*_*_*_ -> _) = 
        FP.curry4 f
        
    static member curry5 (f:_*_*_*_*_ -> _) = 
        fun a b c d e -> f (a,b,c,d,e)

    [<OverloadID("curry5")>]
    static member curry (f:_*_*_*_*_ -> _) = 
        FP.curry5 f
        
    static member curry6 (func:_*_*_*_*_*_ -> _) = 
        fun a b c d e f -> func (a,b,c,d,e,f)

    [<OverloadID("curry6")>]
    static member curry (func:_*_*_*_*_*_ -> _) = 
        FP.curry6 func

But this has problems when trying to curry overloaded methods:

  • FP.curry String.Compare doesn't work, since the compiler doesn't know which overload to pick. (there are ten overloads!)
  • FP.curry2 String.Compare works fine, since we are explicitly telling the compiler the arity of the method, and there is only one overload with two parameters; however:
  • FP.curry3 String.Compare fails, because there are two overloads of String.Compare with three parameters.

Conclusion: this is not a good way to implement generic currying in F#. It would be very nice to have this integrated into the language, but I wouldn't hold my breath. As a workaround, I'll consider implementing a post-build step using Mono.Cecil to create the necessary FastFunc wrappers.

Saturday, January 3, 2009

Implementing interfaces in F#

Ever since the release of C# 3.0 I've been tending to write more and more functional-styled code, thanks to LINQ. So I thought, if I'm writing in a functional way, I might just as well use a real functional programming language! So I went to check out F#. I have been reading about F# for some time, mainly from Tomáš Petříček, Dustin Campbell and Don Syme, but never really tried it.

So, I wanted to start by rewriting a service in F#, a service that is 99% functional (in C#) and so I thought it was a good candidate for trying out F#. This service implements an interface defined somewhere else (another assembly) and is registered in the DI container so it can be injected into other components in the system.

I'm clearing this up because people could say that when coding in F# you do it in a functional style and thus you don't use interfaces. Ok, that may be so for something written from scratch, but most of us code against already working systems implemented in C# or VB.NET which are of course imperative OO languages so interfaces come up often.

For the purpose of this post, let's assume that I wanted to implement IComparer. I started by writing a little test in C#, just to be extra sure that it was interoperable:

[Test]
public void ComparerTest() { 
	var c = new Comp();
	c.Compare(1,2);
}

Then I went to F# side of things and wrote Comp:

#light
namespace FSharpPlayground
open System.Collections
type Comp() =
    interface IComparer with
        member x.Compare(a, b) = 0

but it wouldn't compile. WTF?! The F# assembly compiled just fine, but then the C# compiler complained that there wasn't a Compare method. I pulled Reflector, opened the F# assembly and saw this:

[Serializable, CompilationMapping(SourceConstructFlags.ObjectType)]
public class Comp : IComparer
{
    // Methods
    private int System-Collections-IComparer-Compare(object a, object b)
    {
        return 0;
    }
}

Forget the attributes, why is the Compare method called System-Collections-IComparer-Compare instead of just Compare? And why private? In my ignorance, I thought I was just making some stupid syntax mistake, which happens all the time when learning a new language, so I tried all of these...

type Comp() =
    interface IComparer with
        member x.Compare(a: obj, b: obj) = 0

type Comp() = class
    interface IComparer with
        member x.Compare(a: obj, b: obj) = 0
end

type Comp() = class
    interface IComparer with
        member public x.Compare(a: obj, b: obj) = 0
end

type Comp() = class
    interface IComparer with
        override x.Compare(a: obj, b: obj) = 0
end

type public Comp() = class
    interface IComparer with
        override x.Compare(a: obj, b: obj) = 0
end

...to no avail. They all compiled to the same IL.

Until I found this thread. The problem wasn't the syntax. Turns out, F# implements interfaces explicitly by default (just the opposite of what is normal practice in C#) and it currently has no way to implement interfaces implicitly. So, either you cast the object to the interface when you need the method, or you write a "forward method" that hides the casting from the caller:

type Comp() =
    interface IComparer with
        member x.Compare(a, b) = 0
    member x.Compare(a, b) = (x :> IComparer).Compare(a,b)

This may seem a little odd at first, but when you think about it, it all makes sense since it actually clears up any ambiguity. In my particular case, I just had to change the test to:

IComparer c = new Comp();
c.Compare(1,2); 

And since this was being injected by the container via the interface, I didn't need the "forward method" and no other code had to be changed.

Another interesting way to implement interfaces is to use the object expression syntax which looks similar to Java's anonymous classes:

let CompExp = {
    new IComparer with
        member x.Compare(a,b) = 0
}

But this is really a static instance, so the DI container can't mess with it to inject other dependencies, make proxies, manage its lifecycle, well, everything that containers do.

Another common pitfall while transitioning from C# to F# is that code order matters.

All in all, F# has been gentle to me in my first week with it. It has so many interesting features that it sometimes makes my head spin trying to absorb them. Exciting stuff! :-)