This week has been very interesting so far, and it’s been interesting almost solely because of PDC. (Microsoft’s Professional Developers Conference. Yes, Microsoft.)
C# 4.0 has on the surface very few improvements, but they are deep. There’s our old friend dynamic, using which the compiler types the object as object and defers any further method invocation validation until run-time. (By the way, typeof(dynamic) is invalid, dynamic obj /* .. */; obj.GetType(); will return the run-time type, and in the generated IL, the declarations look like [DynamicAttribute] object.) Work is being done here to unify all of the run-time invocation methods in the different APIs.
There’s optional and named parameters. Optional parameters are more or less functionally a noop in terms of shall we say “turing-completeness”, but the existing technology you’d have to use would be a cartesian product of overloads for all optional parameters, and it falls down if you have two or more parameters of the same type, which is where named parameters come in. They’re not selectors, but if you squint just right, though… foo(1, bar:42, baz:8)… isn’t that MacRuby?
There’s co/ntravariance, which means that you can treat a list of strings as a list of objects in certain circumstances without spending valuable time casting. And there’s lots of COM interop patches, if you spend all your time generating enthralling Powerpoint presentations on realizing synergies and leveraging n-tier paradigms.
What makes C# 4.0 interesting is mining those features for hidden potential. Keen eyes may have noticed that you can now write duck typing code and generally delay binding in C#. Well, no. Here, let me show you:
class Example {
class Animal { }
class Dog : Animal { }
class Giraffe : Animal { }
static Random sharedRandom = new Random();
static Animal FetchMeAnAnimal() {
return (sharedRandom.Next(0, 2) == 1 ?
(Animal)new Dog() : (Animal)new Giraffe());
}
static bool ReachHigh(Animal anyAnimal) {
return false;
// on average, animals aren't that tall!
}
static bool ReachHigh(Giraffe aGiraffe) {
return true;
// giraffes, though... they're tall.
}
static void Main() {
Animal fetchedAnimal = FetchMeAnAnimal();
bool reached = ReachHigh(fetchedAnimal);
// reached will always be false, even if
// the animal ended up being a giraffe
var varAnimal = FetchMeAnAnimal();
reached = ReachHigh(fetchedAnimal);
// reached will *still* always be false; the
// compiler is just inferring "Animal" for you
// try 1
dynamic dynamicAnimal = FetchMeAnAnimal();
reached = ReachHigh(dynamicAnimal);
// WON'T WORK: you're calling a method taking a
// statically typed parameter, and there's no
// conversion. compile error.
// try 2
reached = ReachHigh((Animal)dynamicAnimal);
// WON'T WORK EITHER: now it's a static type,
// but since you're casting it down to an Animal
// the compiler will make sure the Animal-taking
// overload is called.
}
}
Actually, there’s no way that I can find that has reached be false when the dog’s fetched but true when the giraffe’s fetched, save for a sane implementation of the above problem. The problem wasn’t designed to be sane, but to highlight this problem. This leaves precious little duck typing ability in the language - what dynamic properties or methods you can exploit rely on foregoing static typing entirely and using dynamic at every step of the chain. If you were holding out for this, you were looking for the wrong language - at least you can take solace in being able to define the hilarious method static dynamic Foo(), though.
What has me really interested in PDC is the relatively open structure, though. Talks are available to watch and download on Channel 9 for free without registration, and I downloaded the Visual Studio 2010+.NET 4.0 virtual machine and tested every line of code written in this post. This is definitely something I wish Apple aped. Not everyone can go to WWDC (especially sold-out ones), and I’d like to see the sessions, even for a modest sum.
One of the talks is The Future of C# where Anders Hejlsberg goes into detail on the new C# features. It’s a well-done talk. Anders acknowledges the “hack” of statically typing some objects as being dynamic and draws laughters, and thanks to the dynamism and interop features rewrites some JavaScript in a HTML page hosting a Silverlight program in C#.
The best oohs and aahs come at the very end, though, where Anders demos the upcoming (post-2010, sadly) C# C# compiler — that is, a C# compiler that’s also written in C# — which can be used as a service. Quickly, a Read-Evaluate-Print shell (”C#>”) is assembled and is made to do shell-like things as everything entered is compiled and appended to the running assembly.
Anders touches upon something I think most people were wondering about at that point. With all these dynamic features, it still won’t integrate very well, and we can’t really do metaprogramming at the level that we might like to, which is one of the major points of dynamic languages. The C# compiler service classes will be able to return the output as an abstract syntax tree which you can remodel at will, making refactoring and (premature?) optimization possible. That something like this exists and is pushed even by C#’s creator and architect stands as a great credit to the .NET platform and to Microsoft. It is probably the most exciting thing mentioned at PDC in the same sentence as “software” and “service”. This kind of thing is where we’ll need to go in the future.
Moreover, I advise that the iPhone software platform must be opened.