Java and C#
I want to start by first doing a quick comparison between languages on the JVM and .NET. The main differentiators that I see between the JVM and .NET are twofold: –
The JVM is much more common on non-Windows servers e.g. LAMP stacks. Yes, there’s Mono, which is becoming more popular, but generally this domain is taken by Java. Between the two most popular languages across the two platforms – Java and C# – Java has slowly stagnated over the years, caused apparently by over-deliberating by committee on details of various features whilst C# has gone steaming ahead and introduced genuinely revolutionary features to OO developers such as queries and asynchronous programming as first class citizens, and also functional programming constructs.
Whilst Java (and indeed the JVM) has a fundamentally limited implementation of generics which will likely never change, C# and .NET have generics baked throughout the runtime. Whilst Java 8 will (in 2014) finally get lambda expressions (something which I remember Java developers passionately castigating in 2008 when C#3 first came out), again, because it doesn’t have a notion of a delegate, it won’t be as elegant as the C# implementation, involving (as I understand it) compiler tricks to turn lambdas into single method interfaces.
One thing both Java and C# do have in common is that they are rapidly becoming languages that will be prevalent on the server-side, notwithstanding e.g. internal LOB applications or native mobile applications (even that’s a bit of a hot potato with things like Xamarin – maybe best left for a discussion on another day).
The good, the bad and the ugly of C#
So C# has given us developers some pretty good things. Yet in a sense, since C#3 came out, the language hasn’t moved forward that much. Dynamic was introduced, we got better co- and contra-variance, and C#5 introduced async/await. All excellent features (particularly the last one), but where do we go from here? I’ll go back to my comment about lambda expressions on Java again here. Some of the main criticisms of LINQ when it first came out by the Java community were driven by emotion rather than rationale – that LINQ was just a poor man’s SQL embedded into the language; that C# was now a dynamic language; that extension methods would somehow break encapsulation; that LINQ was just Microsoft’s latest attempt to get new customers and it “wouldn’t work” etc. etc. All nonsense, yet one underlying message from the complaints was that lambdas and LINQ would be too confusing for developers. To an extent I think that this is more of an issue in the Java community, where I see the language being far more OO than C# is nowadays.
But, at the same time, think about a new developer learning C#. There are already many ways to achieve the same thing at both the language and framework level e.g. set based operations, asynchronous operations, multi-threading etc. etc.. Think how many constructs and fundamentals that there are to learn these days; you’d probably get contradictory information and advice from ten experienced .NET developers that have picked up different bits over the years. At least we’ve been drip-fed C# over the years at a rate we can absorb 🙂 whereas a new developer will have to try to distil that information to a manageable amount. It’s harder and harder to know the “right” way of doing things.
There are some things in the language that we’ll probably never get – things like non-nullable reference types, which would eliminate whole classes of bugs, or the removal of leftovers from .NET 1 that were replaced in .NET 2 like non-generic collections etc., or the multiple-ways-to-do-async etc. etc.
Where does C# go from here? Do the designers continue to add features to it e.g. immutability / more succinct type declarations (something I’ve been hearing might well happen) / improved type inference (something I would love to see)? As each revision of C# goes in, it becomes harder and harder to add new features to it. On the other hand, languages like Scala on the JVM and F# on the .NET framework are changing at a much more rapid pace. Ironically, Scala, to me, seems to me more like C# than F# with its objects-first-but-functional-programming-supported approach, but both it and F# are introducing features to their respective communities.
Is there a case to perhaps keep the changes in C# at a relatively sedate pace now, before it becomes even more complex, and let e.g. F# push the boundaries with new features? What features do we need to see added to C# to improve the programming experience without making the language a mish-mash? Added to this is Rosyln – what impact will that have on the language going forward?
I suppose the main upshot is that I think the days of mega-changes in C#, like we saw in C#3, are over. What I suspect we’ll see in the future are most likely carefully-thought-out smaller features which can improve the experience or perhaps deal with specific problem domains but won’t necessarily change the fundamentals of C# as we saw with LINQ.