The Rubification of C#
18 Dec 2007Chad Myers gave me a nice little surprise by using my surname in his blog post "Moore on the Anonymous Delegate Approach" about an approach to make his statically-typed C# code more easily testable. I struggled with how best to respond because the subject of his code experiments really demonstrates some of the things I've been thinking about C#'s evolution for a while now. So while this isn't a direct response to his post, its something I've been wanting to say for a while now.
Chad started out by showing how you can use anonymous delegates to encapsulate your logic, and then swap out the delegates in his test cases so he can verify the dependent objects work properly. So he is essentially swapping the implementation of the code his object has a reference to. The fly in the ointment is that only the original anonymous delegate can access all the internal data in his object, so once you swap out the object's original anonymous delegate, the object becomes ineffective. (Unless your logic is dead simple, like the kind you use when you are writing code demos.)
The thing I really like about Chad's code is that he's getting really close to using anonymous delegates as closures, and I really love closures. I believe if Microsoft would (or could) add closures to the C# language (and idioms) that C# would be better for it. But closures aren't embraced by C#. I understand that he is finding new ways to solve the testability problem with static languages, and while I enjoy his ingenuity, I'm starting to think that C# is moving too far from what it is. My concern is that as C# tries to be all things to all people, it simply stops being as useful.
Coincidentally, Tim Bray posted his thoughts on adding closures to Java yesterday, and he said many of the things I've been thinking about in regards to C# and Ruby. The only caveat I'd make on applying Tim's thoughts to C# and .NET is that Java Generics != .NET Generics. Essentially, C# is an 80% language, and I'm totally okay with it. Ruby is also an 80% language, although a much different 80%. Making C#'s 80% overlap overlap Ruby's 80% as much as possible seems kinda wrong.
Tim's favored approach to improving Java is to work on a multi-language VM, not the core language itself. .NET is already ahead because it has facilities for interoperating multiple languages. Therefore I don't think we should focus on improving C#, but we should start focusing on using the right tool for the right job; meaning the right language. Don't get me wrong, I appreciate the fact that C# is taking on many Rubyisms in an effort to improve. But C# will never be Ruby, and really it never should. My hopes are that the DLR enables C# and IronRuby to not just co-exist but integrate well.
In this Channel9 video Robert Martin and Chad Fowler discuss dynamic vs. static languages at JAOO 2007. You should watch this video now. In it, Uncle Bob was asked if he was excited about the new functional programming features of C#; specifically LINQ. His response? "I'm about as excited about that as I am about Fortran 95." His point was that by the time the new Fortran was released he had already moved on and it was no longer relevant to him. That is certainly how I feel about C#; the more features they add, the more desperate it looks, and the less I feel like investing myself in it.
Static languages have failed. They aren't dead, but they aren't the future. You can only fight a language so long before its time to move on.