A couple months ago I made a post called What do you want in C# vNext? that outlined what *I* wanted out of C# 4.0. I have to say that it's the first time I've ever been flat out angry about the comments on one of my blog posts. I think in retrospect I wasn't clear about why I wanted this stuff. To review, my original list was:
- Mixin's. I found myself really wanting this for a framework I have in my current project. Extension methods are okay, but I'd rather make it all the way to Mixin's. Obj C can do it as a static typed language so it's definitely possible. Heck, you can kind of do it in JavaScript. I really want to do this dynamically or at least declaratively. Inheritance tricks don't count. The solution presented here for C# 3.0 falls a bit short of what I'd like to have (but it's better than nothing). Real mixin's would give you the ability to mimic "multiple inheritance" in one wave of the hand, and reuse the Mixin code over multiple classes. Extension methods by themselves are nice, but fall well short of mixin's. Of all the things that I asked for, this seems the easiest to do.
- Symbols. Reflection based solutions could be so much easier with Symbols. I'd love to have compiler safe equivalents to Ruby Symbols. Actually, what I wanted this for is somewhat possible in C# 3.0 with lambda expressions. It's ugly compared to its Ruby counterpart, but I think we'll get a lot of usage out of it. All I really wanted was to say something like "map :propertyName to "nodeName" where ":propertyName" would basically be a pointer to a property. I was looking to do declarative mappings (class to Xml, domain model class to DTO, WinForms control to Model class, etc.) in a compiler safe kinda way. Interned strings aren't an equivalent to what I wanted here.
- Make hashes a language feature. I keep bumping into frameworks that really want to pass around hashtables. If you absolutely have to do that, I wanna do var hash = :key => "red", :key2 => "green" in one line of code. Somebody recently commented that object initializers might be a decent compromise. Yes, I do know that there is such a thing as Dictionary<T,V> in .Net. I'm not an idiot, I just want a syntax for building hashes in less code. Take a look at the new MVC framework or the Workflow Foundation and all of the hashtables that they sling around. Wouldn't it be nice to write less code here? All I really want is some syntactic sugar here. It'd also make something in StructureMap nicer too, and that should obviously be MS's priority.
- Automatic delegation ala Ruby or Objective C. No, this isn't the exact same thing as a Mixin. I was thinking about having an equivalent of Forwardable in Ruby. There are a lot of places where you're explicitly setting up forwarding from the public method of one class to an inner field held by that class just to avoid Law of Demeter chaining and protect encapsulation. Ruby's Forwardable makes that ridiculously simple. C# has to be done explicitly with more noise code.
- Metaprogramming! Method Missing magic! I'm not holding my breathe on this one because it sounds like a bridge too far for me. Give me metaprogramming and mixins and I think we can do AOP like things with less effort. Simply a bridge too far with a static typed language. In 2002 I was building a large system in VB6 and looking longingly at Java wishing I had the fullblown OOP toolkit. I feel the same way today about C# coding and watching the Ruby guys shrink their codebases with metaprogramming.
- Everything is virtual by default to make mocking easier. The sealed by default rule that Anders picked for performance is annoying. I'll grant you that it isn't nearly as annoying as checked exceptions in Java though. I know the TypeMock enthusiasts like to crow about being able to mock anything, but doesn't it bother you that they had to resort to IL injection techniques just to make a freaking test seam?
- If I'd been thinking, I would have said the most important little request was getting Map/Reduce in a little bit smoother than the Array.Find methods. That's a can do with extension methods.
Do we need C# 4 at all?
After a lot of conversations about the future of C# at DevTeach and on whatever the altnetconf list is called now, I've somewhat changed my mind. If you look in my list above, I'm wanting C# to be more like Ruby or Python. More functional programming would be nice too, but Anders and co. seem to have that covered a bit in 3.0. Doing the things that I want makes it into an entirely different language. Maybe that's just plain wrong.
There's no possible way that MS can make everybody happy with one single language. *I* think the type inference added in C# 3 is great for understandibility because it reduces code noise. Other people want even more type inference like some of the functional languages (Haskell or Scala). Even other people think that is a horrible idea because they think it degrades the understandibility of the code (some people apparently remember the VB days before Option Explicit). I want more dynamicism but other people want even more ways to explicitly express contracts in the code instead. That's a significant difference in direction. We can't all be happy with one language unless it grows immensely -- which would probably degrade C# until a drive starts to replace it with a simpler language and start the whole cycle over again. Instead, let's embrace polyglot programming and use more than one language. F# is a nice addition to the .Net family and I've got a side project lined up to give it a go soon. Give me my IronRuby (or Ruby.Net). Keep C# a static typed mainstream language. Do whatever you want with VB.Net.
Let's call C# done and move on to other languages. Maybe add spec# because that seems pretty cool, but otherwise, let's basically seal the deal. MS only has so many people and resources to go around. Instead of stretching C# farther, how about they move some people onto IronRuby and speed up it's schedule? The initial excitement about the new MVC.Net framework seems to be fading because it isn't quite Ruby on Rails. Fine. Move IronRuby along faster and we'll just use Rails running on the CLR (with acceptable performance) and be happy. Invest the time in better tooling around Ruby to simulate compile time checks and other forms of code analysis. Give them their due, if anybody could do a great intellisense for Ruby it's the Visual Studio team.
Improving the Language or Improving the Libraries
A lot of people are either upset with the idea of Microsoft making changes in C#, or simply want to see that energy go into better or at least more libraries or frameworks instead. My perspective is that more frameworks or libraries represents artefacts that may or may not be useful to me. Better programming languages enable me to more readily build my own code that serves exactly my needs. A more expressive programming language can reduce maintenance costs by making the code more intention revealing. Given a choice, I'll take the better language because of it's greater applicability.
D
A couple commenters said "why not just use D?" Um, because it's a fringe language that isn't mature yet? If you haven't heard of it, the D language is being positioned as the Subversion to C++'s CVS. I talked to some folks about this recently and our collective opinion about D was that it would have been the bomb if it could have rolled out 10 years ago.
For that matter, a lot of what I wanted is already in Objective C. That might be worth checking out. The handful of times I've had to read Obj C code I thought it was incomprehensible, but that's probably just unfamiliarity.
Posted
Wed, Jan 2 2008 1:42 PM
by
Jeremy D. Miller