Tuesday, May 6, 2008
Complaining about .NET 3.5
Saturday, May 3, 2008
Multimethods in C# (Part 1)

We have a collection of SpaceObjects that we update in a tight loop. We need to handle collisions between these objects. For example if a TIE-Fighter collides with an asteroid we might want to apply damage to the space ship and replace the asteroid with several smaller asteroids. One way of doing this is to determine the concrete type of each SpaceObject and then call one of several overloads to handle the collision:
bool Collison(SpaceObject leftSpaceObject, SpaceObject rightSpaceObject)
{
TieFighter tieFighter = leftSpaceObject as TieFighter;
Asteroid asteroid = rightSpaceObject as Asteroid;
if (tieFighter != null && asteroid != null)
{
return Collision(tieFighter, asteroid);
}
XWing xWing = leftSpaceObject as XWing;
if xWing != null && asteroid != null)
{
return Collision(xWing, asteroid);
}
//try again with reversing left and right parameters
// and on and on for every combination of every object in every order...
}
bool Collision(TieFighter tieFighter, Asteroid asteroid)
{
// handle collision
}
bool Collision(XWing xwing, Asteroid asteroid)
{
// handle collision
}
The method that dispatches to the correct overload smells. It is error-prone because you have to be careful to cast in order from the most derived to least derived classes. Failure to do so will not result in the most correct method being selected. It is also repetitive because all of the information required to write this code can be inferred from information you've already declared in your overloads and your class definitions. It's also a maintenance nightmare because if we make any changes to the class hierarchy we will need to remember to update the method.
Multimethods
Essentially we want virtual method dispatch but we need it on multiple types and we need it bound at run-time because the compiler can't know enough information to do it at compile-time. This is exactly what multimethods allow us to do. In a compiler that supports multimethods you simply declare the various overloads and the compiler ensures the correct overload is called. Here's what this might look like if it were added to C#:
// when invoked this checks argument types and dynamically dispatches to overloads below
multimethod bool Collision(SpaceObject obj1, SpaceObject obj2);
bool Collision(TieFighter tieFighter, Asteroid asteroid)
{
// handle collision
}
bool Collision(XWing xwing, Asteroid asteroid)
{
// handle collision
}
bool Collision(TieFighter tieFighter1, TieFighter tieFighter2)
{
//handle collision
}
// and so on for all cominbations...
Unfortunately there is no "multimethod" modifier in C# and it's quite unlikely there ever will be. Thankfully C# 3.0 does have a feature which allows us to seamlessly add this feature: Expressions.
Adding Multimethods to C#
Let's create a library that examines our class hierarchy and a group of method overloads using reflection and then creates the method that does the dynamic dispatch for us. We'll design it so it has the following API:
var collision = DynamicDispatch.CreateFunc<SpaceObject,SpaceObject,bool>((obj1, obj2) => this.Collision(obj1,obj2));
// dispatches to Collision(XWing xWing, TieFighter tieFigher)
collision(new XWing(), new TieFighter());
What's going on here? The CreateFunc method accepts a lambda in which the most abstract version of the collision method is invoked. It returns an instance of Func<>, a new delegate type introduced in C# 3.0 that wraps a method that returns no arguments. How do I manage to generate the code required to do dynamic dispatch from a lambda function? I'll cover that in the next installment. Stay tuned. :-)
Tuesday, April 22, 2008
Using Operators with Generics

Attempt to compile this will fail. The compiler chokes on the following line:
output[x,y] = (value1.numbers[x,y] + value2.numbers[x,y]);
The compiler can't confirm that type T will have the + operator. Normally the way you resolve this is by using a constraint. However there is only two kinds of constraints: type-based and constructor-based. The operators aren't part of an interface and I'm not sure they should be. A better solution would have been for C# to allow operator-based constraints. After all, an exception is made for constructors. They may have decided against this route for CLS compliance. We'll probably never know.
All this conjecture doesn't get us any closer to our Matrix class. There are two ways of getting what we want. The first is reflection. In fact, if you are using late binding VB.NET will compile a modified version of the code above happily and resolve the operator using reflection at run-time. Reflection is slow though and typically we want math operations to run quickly.
That leaves us with code generation. I've been talking alot about Lambda Expressions in recent posts. Lambda Expressions are a new .NET 3.5 feature that makes it easy to generate methods on the fly quickly. The code below is a refinement of the work done by RĂ¼diger Klaehn. He uses low-level IL generation API's available in .NET 2.0. Observe how his code can be simplified dramatically by using lambda expressions instead.

This class creates and compiles expressions for each of the operators (only addition shown above for brevity). The lambda expression worries about exactly which add method to bind to based on the parameter types when it is compiled into a delegate. Pretty readable eh? Now let's rewrite our Matrix class.

Notice that the consumer of our API doesn't need to futz about with the Num class at all. They use the Matrix exactly as they would expect to:
var leftMatrix = new Matrix<int>(new[,]{ {2,2,1},{5,2,1} });
var rightMatrix = new Matrix<int>(new[,]{ {1,2,4},{1,9,1} });
var newMatrix = leftMatrix + rightMatrix;
So what's the catch? You lose static typing. If you parameterize the Matrix class with a type that doesn't have the operators defined it will trigger a run-time error. There is no way around this because there is no way of confirming the operators exist at compile-time. Does this make you uncomfortable? Get used to it.
Many statically and dynamically typed languages are gradually moving towards a new model: Static Typing Where Possible, Dynamic Typing When Needed. VB.NET is already there with its optional late binding. A similar feature is being discussed for C#. If you do a lot of work with run-time code generation you will begin to notice two things:
1. You will have to compromise on compile-time type safety more and more.
2. You will find yourself caring less and less.
Static typing is a tool, not a religion. Frankly it was never very useful for assuring program correctness and if you are test-driven it is even less useful. Static typing is most useful as metadata for your development tools. It often makes sense to live without it in specific cases where doing so prevents you from repeating yourself. Using code generation to avoid writing identical Matrix implementations for each numeric base type is an excellent example. Can you think of any others?
Sunday, January 6, 2008
Misunderestimating C# 3.0
Unfortunately he misses the mark with his criticism of type inference. Take a look at his code sample:

Look at the portion highlighted in red. Dare laments that he cannot write new {Weight = voteFunc(item), Item=item, FeedTitle = feedTitle } and must instead create a Vote class. The reason for this is that he is adding votes to a List and to instantiate this list he must parameterize the generic List with the Vote type.
Now let's rewrite that code snippet using the idioms of C# 3.0:

I wrote the ToProjectedDictionaryOfLists function. It is an extension method on IEnumerable<T> and it accepts two lambda functions. One that accepts an item in the stream and returns a key for the dictionary and another that accepts an item in the stream and converts it into a different representation ("projects" it). Using these functions, a key and value is derived for each item in the stream. This information is used to populate the dictionary with lists of items that share the same key value.
It's important to notice four things about our replacement code:
1. We've specified no type information (type inference in full effect)
2. We've liberated the code that moves the data into a hash table from the code that creates the code.
3. We've abstracted the action of creating a dictionary of lists from a stream of data into a reusable function.
4. We've expressed the problem in such a way that it can be trivially parallelized.
In previous blog posts I mused that Linq's superficial similarity to SQL might keep developers from realizing how widely applicable it is. Dare mentions Linq in the article but fails to recognize that he could use it to improve his example code in every measure.
This is really about functional programming vs. imperative programming. Because of its inherent advantages developers should always try and solve a problem functionally first and fall back to imperative solutions only where the result is more readable. In C# a functional solution was rarely more readable because the language lacked the idioms to support it. C# 3.0 makes huge strides in this area. This should have a profound effect on the way you code. If your C# 3.0 code looks like your C# 2.0 with "var" statements and the occasional Linq query against a database you've got to some remedial reading to do. :-) Trust me, you'll be glad you did.
Here is the code for the ToProjectedDictionaryOfLists function:

Tuesday, December 4, 2007
ParallelFX CTP released
Tuesday, September 18, 2007
Finally some news on PLINQ
Thursday, September 6, 2007
The Luddite Developer
Throughout the short history of commercial software development we see the same dynamic repeat itself again and again: 1. New abstractions are introduced which increase developer productivity. 2. Developers resist these abstractions because they a) legitimately need to maintain low-level control to satisfy requirements OR b) they don't want to learn the new abstractions and tools required to use them 3. The developers that resist for reason b either suffer or eventually capitulate because of competitive pressure. When C was created many assembly developers resisted using it even though the benefits were obvious. Many C++ developers still resist writing client applications in Java and C#. Many Java developers still resist using slower, more powerful languages for writing web applications where performance is far less important. In some cases these decisions are justifiable (see reason a) but they are edge cases.
When a developer chooses, all other things being equal, to use a low-level abstraction instead of a high one it’s worth asking them why. If they attempt to justify their decision on the grounds of “simplicity” chances are that they are motivated by reason b). High-level abstractions are simpler than low-level ones by definition. They reduce code size and increase code clarity. Most of the time what the developer is really saying is “I didn’t want to learn anything new.” So why do some software developers resist learning new things? It’s not laziness. A developer who manually writes the same code with slight variations a hundred times and spend countless hours maintaining it can hardly be accused of being lazy. The real reason is that they are afraid of new technology.
So how can a software developer possibly be afraid of technology? Two words: cognitive dissonance. These individuals spend their lives creating technology to improve the productivity of accountants, managers, and housewives but insist on coding GUI’s by hand. They use REST instead of web services because they don’t want to learn how to generate a proxy. They’ll write reams and reams of repetitive code instead of learning a new domain-specific language and every argument they’ll use to justify it can also be used to argue that they should get rid of their compiler and write bytecode by hand.
It’s easy to understand why software developers can be afraid of new technologies. Software development is extremely challenging for many reasons. Once having successfully developed software using one set of abstractions a developer would be wise to consider carefully the decision to learn new ones. This is why it’s so important to familiarize yourself with a variety of different platforms, technologies, and development approaches before you are put on a deadline. Once you understand the strengths and weaknesses of a variety of development paradigms, platforms, libraries, and tools you can stop wasting time fearing the unknown and start fearing the known.
Do you know any luddite software developers?
About Me

- Jafar Husain
- I'm a software developer who started programming at age 16 and never saw any reason to stop. I'm working on the Presentation Platform Controls team at Microsoft. My primary interests are functional programming, and Rich Internet Applications.