VB and C# Coevolution
As we are approaching the release of VS 2010, I have seen a number of questions from customers about our language strategy for VB and C#. We made a shift in strategy at the beginning of this release cycle and have been talking about it publicly for some time. A lot of this discussion has been in forums that have a lot of early adopters, for example at PDC and other conferences, so I suppose it’s natural that we continue to see these questions. I thought it would be valuable to share my thoughts on this in blog form.
For starters, I should explain who I am and what my role is in this area. I’m the Product Unit Manager for Visual Studio Languages. In this role, I manage a portfolio of .NET languages (VB, C#, F#, IronPython, IronRuby) and the Dynamic Languages Runtime. I have a long history with VB (I interned on VB 1.0 before working on OLE Automation, VBA, VB4, and VBScript) and C# (I am one of the original C# language designers).
VB and C# both enjoy broad adoption. The most reliable numbers we have on the two languages show roughly equal adoption for the two. Together, these two languages represent the vast majority of .NET usage. As such, they are critical to our long-term developer strategy.
Our strategy for VB and C#, beginning with VS 2010, is a coevolution strategy. This is not the typical strategy for a portfolio of items. The more traditional portfolio strategy is to differentiate them, as P&G does for laundry detergents. For several versions, we tried to do this. We had an explicit strategy of differentiating VB and C#. We wanted VB to appeal to VB6 developers, who tended to build business-oriented, data-focused solutions. We wanted C# to appeal to “curly brace developers”, including C++ and Java developers, where there were more enterprise-class and ISV solutions. In practice, we found that it was quite hard to differentiate the two, due to the presence of several powerful unifying forces, which I describe below.
A modern developer experience for a language is formed through a combination of elements:
· A “horizontal” runtime like .NET that provides runtime services and libraries that are broadly applicable.
· A “horizontal” IDE platform or shell
· A set of “vertical” platforms and tools for building various kinds of software – Windows, Web, Device, Database, and on and on
· The language and associated language-specific tooling, e.g., IntelliSense and refactoring
Three of the four items above are common building blocks for VB and C#. This is a significant departure from pre-.NET products, where all of these were differentiated. “Classic” VB was differentiated across all four bullet points – it had its own runtime, its own shell, its own designers, and its own language. For VB .NET and VC#, the shared elements (the first three bullets) deliver a huge part of the overall developer experience. These common IDE and platform building blocks are the first “powerful unifying force” that I am talking about. For there to be language-based differentiation, it has to come from the fourth bullet point – the language and its associated tooling.
The second “powerful unifying force” is the nature of the languages themselves – they are both object-oriented languages and both have strong static type systems. So at a high-level, they are in the same family of languages. In contrast, some other languages in our .NET portfolio share a lot of the same building blocks but are farther afield from a language perspective – F# (functional), Python (dynamic) and Ruby (dynamic). As a practical matter, I rarely get asked why we have both C# and F# J.
There is a third “powerful unifying force”. As we began to evolve the languages after .NET 1.0, we found that the most significant opportunities were on the border between the languages and API’s. Our languages and runtime provide a set of building blocks, and API developers compose these to produce API’s. One way I think about this is that there are two kinds of language features: “on the outside” language features that grow or improve the set of API building blocks, and “on the inside” language features whose scope of impact is limited to the language itself. “On the outside” features include generics and the LINQ language features. “On the inside” features include changes to statements, expression and control flow. If we invented a new looping construct, that would be an “on the inside” feature – it would not impact API developers except perhaps as an implementation detail. We have done several releases since .NET 1.0, and in practice we have found that the best opportunities for language evolution and innovation have been in “on the outside” language features rather than “on the inside” ones. The most significant advances have been in “on the outside” features.
API designers are of course interested in having their API’s used by the broadest set of languages. To ensure this, we designed a Common Language Specification as part of .NET 1.0, and have evolved it in subsequent versions as we have added significant new building blocks. This approach helps us ensure that .NET API’s from Microsoft and others are accessible to a wide variety of languages. In practice, this also ensures that language evolution “on the outside” of languages cannot be used to differentiate languages. Thus, the third “powerful unifying force” is the Common Language Specification and trends in language innovation toward “on the outside” innovation rather than “on the inside” innovation.
Finally, we found that differentiation of language-specific tooling typically resulted in mixed feedback from customers. When we did a feature for one language but not the other, we received positive feedback from the language audience that got the feature, and negative feedback from the other. We found that the VB and C# customer bases were somewhat different, but not different enough so that they would want language tooling that was different. There might be differences in the priority of a particular feature (for example, edit-and-continue debugging for VB vs. refactoring for C#), but that in the long run, both customer bases would want the union of the features. Thus, the fourth “powerful unifying force” is customer feedback on language tooling.
For these reasons, we have adopted an explicit strategy of coevolution for C# and VB. By doing so, we recognize how strong these unifying forces are. We believe that we will accomplish more, and deliver more value for customers, by understanding and embracing these unifying forces rather than by fighting against them.
Our coevolution strategy has several major elements:
· Language innovation. Headliner language features (e.g., generics, LINQ) will be done for both languages, and done in a style that matches the host language. The languages will always be different – we will not try to make them “the same”. Instead, we will evolve them in the same direction, ensuring that both VB and C# developers can benefit from advances in programming models and API’s.
· Language tooling. Over time, we are evolving the language tooling so that customers of both C# and VB benefit from the same language tooling such as IntelliSense and refactoring features. We began this work in VS 2010. We made a lot of progress in this release, but are not 100% there.
· Samples and content. In general, we pursue parity for Microsoft samples and content. For better or worse, our Microsoft platform efforts are quite broadly distributed, and so there are sometimes shortcomings in this area. My team helps advocate for parity by working across Microsoft teams. We engage the VB community to help prioritize this work, so that we are spending our time and money most effectively.
I hope this is helpful context and background for our VB/C# coevolution strategy. Whether you are using VB, C#, or one of the other languages in our broad .NET portfolio of languages, we want you to understand what we’re doing (and why!) so that you can continue to use your language of choice with confidence. I’d be happy to answer any follow-up questions. Feel free to post questions or comments!