I’d originally planned to write on this particular topic in response to increasing outreach to me personally, through my blog and other places, unsolicited, and independently from multiple community members expressing concerns about the health of VB.NET but also their passionate and heartfelt desire and commitment to contributing to its success. I too had been thinking about this, spurred on by comments on the vblang repo, social communities like forums, Facebook and Twitter, but also my own experiences and limitations. Due to recent announcements I’ve had to edit this post somewhat but fundamentally it still makes the point I always wanted to make; what’s changed is the context. It’s not a hastily written result of a last-minute brainstorming exercise or an emotional outburst but the culmination of my thoughts and observations over the last 10 years, 8 of which were spent working on VB.NET at Microsoft. It’s not at all my complete take on the current state of affairs but it is critical for the entire VB.NET community and everyone else watching to be armed with this context when discussing or socializing about anything else, so, I’ll try to provide that first and roll out any further points separately.
Time and time again I see the discussion of Microsoft’s level of investment in VB.NET framed around the same faulty assumption: it’s just too darned expensive and impractical for Microsoft to support two .NET languages (ignoring the fact that they actually make three); it would take an army of developers and content writers at great expense nearly duplicating all effort across the ecosystem at worst or perhaps 10-30% of the (Developer Tools) division resources at best. Today I want to put that misconception to rest.
The difference between where we are now, a position of continual disappointment, dissatisfaction, lost trust, stagnation, frustration, and humiliation; and a place of continual progress and increasing developer satisfaction for the VB.NET community IS NOT AN ARMY of redundant, reluctant, overworked, overcommitted Microsoft employees. Everyone needs to get that out of their heads that that is what this is about—that it’s fundamentally a choice between purgatorial misery for an entire community and hamstringing 5, 10, or 30 of the .NET organization or DevDiv and tens of millions of dollars in salaries. The difference between where we are now and a mostly HAPPY sustainable VB.NET community is…
3-5 developers.
THREE. TO. FIVE. HUMAN. BEINGS.
That’s all. Not an army. Not a percentage. Not millions of dollars. Less than a handful of folks in a team room is enough to *radically* invert the delays, shortfalls, perception, and “forced tough decisions” narrative many of you have observed in the last few years. We know this to be true because we’ve seen it working for 10 years and I’m going to explain it and how we got here so that we all have the facts for thinking about our own next choices and Microsoft’s choices. None of this suffering, depression, and contention is necessary AT ALL. Nothing that’s happened (or not happened) in the last 5 years is about cost or practicality; and malice is not required to explain any of it either. So, let me walk you through the rude Q&A.
How could 3-5 devs make any real difference?
I’ve said that a wildly different reality could easily be achieved with a small autonomous dedicated team of 3-5 people. I know this because we’ve all been watching it work significantly better for TEN YEARS on the F# team. I’ve seen in arguments people say “C# and F# are clearly the priority because…” when for the better part of the last 10 years—it’s entire productized life—F# has had on average 2-4 devs working on in at any given time (and a few times a little as 1) as a whole across the entirety of the company. Full stop. And what has that gotten them?
All of this value in just 3 years, update after update, release after release, continuously, and transparently delivered by a small agile team of usually less than 5 people. Have they had setbacks? Absolutely. At times they’ve been outright excluded from certain technologies and at other times they’ve been perilously understaffed due to attrition but on the whole their users have seen steady progress, leadership, and accountability. They love the product, they love the team, and they’re happy to roll up their sleeves.
VB.NET is an order of magnitude larger than F# but externally people have a wildly disproportionate perspective on it because of the results it can produce because it operates as a separate team from the broader C#/VB/.NET org. At times F# hasn’t even been in the same org as C# at all. Yes, open source is a significant part of that success so I’ll get into that next.
And beyond open source, as a point of comparison, all the tooling support for VB.NET for Windows Phone 7 was implemented and tested by 1 engineer, on the side. The OmniSharp work that lights up C# experiences in VSCode: for quite a long time was just 1 engineer. All of the Windows 8.x samples: 1 engineer. Don’t underestimate the impact 3 developers could have.
“But F# can achieve so much because of its engaged open source community; VB.NET doesn’t have and likely can’t have so vibrant an open source community because… <stereotype>”
F# absolutely leverages its open source community. But a few things to keep in mind. Fostering that community is and has been a top priority of the F# team and that’s something that they’ve been able to do because of their autonomy and they started doing it long before it became popular and VB and C# open sourced. And, I can tell you, having been in the sprintly status meetings where we discuss open source commits and contributions that they would consistently put Roslyn to shame despite the C# and VB communities both being significantly larger (in fact I think VB support in .NET Standard/Core 2.0 was done by an F# community member).
And this is usually when some dudebro in the back stands up and says “But the average VB.NET developer isn’t going to contribute to open source—they <condescending stereotype>!”. Well, yeah. The average C# developer isn’t going to contribute a compiler feature or any feature. The average F# developer isn’t contributing. Open source communities aren’t about average users. VB.NET has more than enough above average folks who want to contribute and have tried to contribute but that desire has to be grown and supported by a group of folks who treat it as a priority. For quite a while (felt like years) I watched the just 2 folks on F# at the time: Kevin Ransom and Lincoln Atkinson where most days all they did was work with their community on PRs and keep the lights on with basic infrastructure or platform work for F#.
“But who would really contribute?”
We’ve already had engaged potential and actual contributing VB.NET community members:
- Adam Speight was one of the first community contributors has made contributions in the compiler and the IDE and prototyped new features.
- Paul1956 took on work to enable comments after line continuation.
- Eric Mutta has tried to make contributions in a number of areas.
- And others have reached our repeatedly both while I was at Microsoft and since about contributions not only in the compiler but the IDE and in documentation and in tests and in partner tools like the EFCore code generator or just templates and samples.
- Current and Former VB MVPs (some now Microsoft employees) have gotten their hands in the code and produced or started to pursue viable ideas.
- Former VB team members who have moved on from Microsoft are out there in the wild, including…
- Me. I am literally a VB community member who has actually written features and product code that ships in the VB.NET product today. VB String interpolation is a feature `$”Written by: {Me}”`. I implemented the initial parsing of `Async` and `Await`. I’ve written Roslyn APIs that power IDE experiences. I implemented the `TypeOf … Is|IsNot`, I’ve prototyped features in the product like multi-line string literals, readonly auto props, byte literals, year first date-literals, and others. Last year I literally prototyped and demonstrated several feature ideas including writing VB code that runs on Android and in the browser without any extra support from the Xamarin tools or ASP.NET Core teams. I am a PURE VB.NET developer. I have never used any other language full-time for any significant portion of my education or career—a client project here or there but nothing that somehow made me NOT a VB developer. How am I supposed to engage?
But a culture of contribution doesn’t succeed in a vacuum. As one VB.NET community member noted to me (last month, I think): (paraphrased) “I normally contribute to making the docs better but seeing the stagnation in the vblang repo makes me not even want to bother doing that”. It’s not a set of individual dials but an ecosystem and the impact of failing in one category discourages all the others.
F# has between 5-15 BIG contributors and a long tail of smaller contributors. I think there are more than enough VB.NET willing and capabledevelopers in the world who could meaningfully contribute to the VB.NET ecosystem if they had 2-3 engaged team members inside Microsoft treating both VB.NET and open source as their first priorities. It doesn’t mean we’d get “everything”; it doesn’t mean that “everything” has to be accepted, but there would mean more blog posts rich with content like what F# has when a new release comes out and less radio silence and excuses.
F# wasn’t born flying with open source, they had to crawl. And supporting their community is a great example of a priority they can make because they’re autonomous and I’ll explain why autonomy matters next.
Why what we’ve been doing stopped working and why you don’t have to assume it’s because Microsoft is anti-VB.NET
The thing about Microsoft—a large international trillion-dollar mega corporation made up of over 100,000 people, many of them quite smart, and quite busy is…
There is bureaucracy there that does not sleep
I’m going to tell a few stories, buckle up.
First story. In 2005 (I think), the VB team, in response to community feedback that the solution explorer was overcrowded with items and visuals which weren’t directly user-created, decided to hide the References node. VB has its own reference management property page (which also manages project-level import directives) so this was technically safe to do. But over time many people grew to find that node useful for various reasons. I joined the company in 2010 and for years when various members of the team (myself included) would go to events or talk to VB developers we’d consistently get feedback “I wish you’d show the References node”). We were pretty confident on the feedback and that we wanted to unhide it in the next release.
It’s a one- or two-line change but the code that hid the node belonged to another team at the time. That team was responsible for a lot that release including a big part of the story for building Windows 8 apps and I politely asked them to unhide the node to make my customers happy and they politely stonewalled me using every mechanism in the book.
- They said, “Well, we shouldn’t just change this thing we didn’t know anything about… if only there was feedback”
- I said, “There was feedback”
- They said, “Yeah, but if only there were a UserVoice request”
- I said, “There is a UserVoice request”
- They said, “Yeah, but does it have votes?”
- I said, “It does”
- They said, “Oh, but the vote count isn’t very high”
- I said, “It’s high for the VB category and we’ve consistently gotten this feedback verbally at conferences for years”
This went back and forth for a while with the goal post moving about. They wanted reports, focus groups, user surveys, UserVoice requests, high vote counts, telemetry, revenue statements and tax receipts from the companies the customers asking worked for. There’s a bit of an adversarial system there for collaboration and the truth is that team was buried in critical work and it was cheaper to burn down my willpower than to have an engineer remove the offending line of code.
A few years later, sometime between 2013 and 2015 the Roslyn team took ownership of the code that caused the references node to be hidden (for unrelated reasons). I went into the office of an old VB IDE team member to find he’d already deleted it. Apparently, it took like 5 minutes. No muss, no fuss, no red tape.
The point of the story is that 5 minutes of real work took 5 YEARS to actually implement not because of any intrinsic complexity or risk to the work or because anybody had malice toward VB.NET users. But because the organizational structure made it very time consuming. Yes, there are mechanisms (escalation) for resolving these disputes but that doesn’t reduce the effort of doing a thing it grossly increases it at a cost of precious political capital and the people who suffered for that (again, sans malice) were the VB customers in those intervening 5 years who couldn’t access that value. Once it reached a state where it could be solved autonomously it was.
I once had a PM argue that VB.NET developers were probably outside of their scenario because “the target for this feature is really large legacy code bases”. (eye roll) It’s not that he was malicious. He was just willing to say anything to defend his team from any more work from anybody. I could tell you other impressively illegitimate pushbacks (like how maybe compiling was outside of the scenario of building projects) but we don’t have time.
I’ve seen features with universal agreement across an org (all teams and managers) still fail to be implemented for years and others implemented only to fail to be checked-in and shipped because of analysis paralysis and a reluctance for anyone to take responsibility or to simply feel empowered to provide that customer value (I originally wrote out those stories but have cut them for pacing).
And on top of that re-orgs, manager changes, and office moves were frequent enough at Microsoft and any of them can reset an entire effort requiring re-discussion, re-validation, and re-approval, and rescheduling. I’ve seen customer value that was only delivered because some courageous principle level developer literally went rogue and “just checked it in”.
Last story (on this topic). For the 2015 release of Visual Studio we’d began with the idea that after a long break without any new features in either language (remember that no new features came in VS2013), we would do what we called “just do it” features. Small, harmless productivity enhancers, many of them long requested from community members, that were low cost so we could get a number of them in the release. And, as had been the case for almost all of the Roslyn project, VB and C# were handled by a single unified team (more on this later). So, here’s what happened: VB design meeting put together a list of great small features. C# design meeting put together a list of great small features. The VB features were fairly low risk (but not necessarily low value) and the C# features started out similarly (some were just analogs) but certain differences in the design philosophy of what was enough or “a little more” or “properly generalized” on the features meant that the C# versions of those features became more complex over time and riskier. So, we (I was on that unified team) tactfully decided to front load the C# features because we could get earlier feedback and uncover more risk and since the VB features were all pretty straightforward, we could circle back to them a little later in the product cycle. But the C# features just kept growing and growing and getting more complex. Then an asteroid hit campus or something and there was an unexpected schedule contraction and now instead of having a year to wrap up we had like 3 months. Ultimately the C# versions of the features grew to such complexity and some of them actually grew out of being useful entirely and most were cut AND almost all of the planned VB features had to be cut and there I was starting VB String Interpolation after officially we were “feature complete” just to ensure VB customers would get any big value that release. To be clear, another team member was writing C# string interpolation in the same timeframe. It wasn’t that C# was in a good place either. Multiplexing the team, combined with the C# natural progression of the design approach had eaten so much of the schedule that when disruption happened it negatively impacted BOTH languages. I’m not complaining about the C# design approach, to be clear. I absolutely get why they design how they design—it creates a consistent language philosophy for C# users. I’m just stating that multiplexing the same team to manage two languages failed hard. Maybe I could have anticipated that, or the inevitable schedule disruption. Maybe I could have been more contentious about it in the beginning or the middle but I shouldn’t have had to be. That same set of circumstances had no real impact on what F# delivered in VS2015.
So, there was a chaotic system and an organizational structure on top of that system that could not react to disruption and the wheels ground to a halt. Whether it’s because of thread starvation or context switching or deadlocking or whatever processing analogy you want to come up with that approach repeatedly failed for reasons completely devoid of malicious intent.
“Well it sounds like there’s some dysfunction. There’s the problem! Shouldn’t Microsoft fix that so that they can get the current model to work for VB too; isn’t that the ideal?”
Nope.
C# and VB have worked under what I call the distributed model, where there’s some experience scattered across multiple teams. And for C# that generally works for a number of reasons—usually getting C# to work is essential to drafting the infrastructure and design of whole systems and platforms. But there are plenty of times where taking the same approach for VB.NET isn’t needed, doesn’t work, or does more harm than good.
For example, samples and templates. It’s not enough for another team to create a template. The “VB owners” have to review and modify all of those templates with VB specific knowledge. For example:
- Should this project use VBCore?
- What should the default project-level imports be for this project type?
- Do the default items and item templates for this project make use of or work correctly with a project root namespace?
- Does this project enable or disable the prescribed set of VB recommended warnings?
- Does this project template correctly exclude an explicit setting for project-level Option directives? This is essential in order to respect each user’s VS wide project default settings which are synced to the cloud: if there’s an explicit setting in the file VS won’t override it with the user’s stated preferences.
- Are certain items appropriately nested (or not) under the My Project node?
- Etc.
This list of checks is even larger for samples because there’s usually more code. Some are functional but others are stylistic like:
- Did the person who wrote this sample use `Object.ReferenceEquals` because C# doesn’t have a reference equality operator and these uses must be now be updated to use VB’s `Is` operator?
For actual functional changes they have to be tested for working with the VB tooling and experience. Even with automated tooling there’s still a manual process that has to take place and it has to be done by people who actually understand VB and its features and how to leverage them best. And it often has to happen multiple times when samples or templates are updated pre-release. No one really benefits from the other team “owning” any of that work (or front-loading it) and just getting a bunch of bugs filed on them. It’s an unknown quantity that they may not have the capacity or capability of completing. And even in the event that that work is prioritized through escalation that creates a culture of tension and adversarial defensive hyper-vigilance rather than collaboration because these ticking time-bomb work items have the potential to seriously disrupt partner teams. It’s not a just a symptom of collaborative dysfunction; it causes collaborative dysfunction.
That’s for external teams but for the C# language this is especially untenable for all involved because C# advances the .NET platform. I’m not begrudging or envying them that role but recognizing that that’s what the language has always done where VB is traditionally focused on innovation in experience. It’s not that you can’t write a library or a framework in VB (and people have) but the .NET platform is not and will never be dependent on the VB language (or F#) to make leaps. But if C# is late developing generics, .NET 2.0 doesn’t ship. If C# hasn’t figured out the shape and behavior of nullable value types those types can’t appear in any new APIs. If it’s late on LINQ, .NET 3.5 doesn’t ship. If async isn’t complete, .NET 4.5 can’t ship with new asynchronous APIs. If C# language design can’t converge on ref returns or nullable annotations the platform teams (like mscorlib) that depend on those features literally cannot ship their platforms for anyone. And for what it’s worth, C# is ALWAYS late on those things (a fact I learned too late) because getting it right takes all the time in the world. Which is why it’s insane (in hindsight) to envision an “ideal” world where you couple or serialize a language which does not fulfill that mission critical role with so many downstream dependencies and its customers’ productivity with one that does and expect good things for both of them.
And no one is trying to move F# to this model.
In the past when Microsoft was more closed source and teams were a lot more possessive about their code maybe this was the only way to do it but the culture has changed there. It’s a lot easier to just submit a PR (even internally) from the team that owns VB and have that team review and sign-off as needed. Things have changed and there’s room to change for the better because of it.
“But a small dedicated team doesn’t scale!”
Is the status quo scaling? Are we tired of scaling yet?
I’ve had the same # of cores in my desktop for the last 8 years; they’ve scaled to everything my computer has done in that time. Nothing didn’t happen because the # of cores was fixed. The current model for VB.NET has literally “scaled” to 0.
Which brings me to…
How did we get here?
In any situation it’s easy to imagine that things have “always been like that” or that they “must be like that for a reason”. There usually are reasons and sometimes those reasons were valid once and are no longer and need to be re-examined. Let me take you on a trip through time…
- In the beginning (VS2002-VS2008), VB was its own product unit. You could actually buy VB.NET as a standalone product and it had its own budget, staff, marketing team and everything. C#, I believe, started out as a part of the C++ PU until it got big and moved out. Everything that happened in VB.NET up until around 2008 (LINQ) was from the VB PU, and everything in C# from the C# PU. There’s a picture from that time of Anders and like 50-100 people working just on C# (wearing C# T-Shirts) so I guess they had a lot of people and VB had a similar number of people. As many of you will recall, this split led to lots of good stuff but different good stuff and there was some wailing and gnashing of teeth.
- After VS2008 co-evolution came and VB & C# were merged into a single PU: Visual Studio (Managed) Languages or VSL. Eventually F# and the Dynamic Languages IronRuby and IronPython, were part of this org.
- When I joined VSL in 2010 here’s what the layout of VB (approximately):
- VB Compiler Dev: 5+ devs + 1 lead
- VB Compiler Test: 4+ testers + 1 lead
- VB IDE Dev: 5+ devs + 1 lead
- VB IDE Test: 4+ testers + 1 lead
- VB Community PM (Beth/Lisa)
- C# had the same layout so both VB and C# had ~25+ people working on each language them across their IDE and Compiler & 4 full-time PMs each.
- F# always had a single PM who owned everything and their compiler and IDE teams were merged but they still had dev and test separated out so it was probably a third the size of either VB or C#. Let’s say ~9 people, not including Don Syme.
- There were a couple extra layers of management for each discipline and each layer but it was a little lopsided.
- After VS2010 we started working on VS2012 and Roslyn (which we thought would ship in VS2013 but ended up shipping in VS2015) in parallel. The team split with some folk working on VS2012 and some working on Roslyn. A combination of diminished scope and the usual staff reshuffle after a release as people move on to other teams really shrunk down the VB and C# hierarchies a bit. Completely accidentally every “team” on either version was missing one person in either a leadership role or a particular language so we consolidated some for efficiency reasons (at first).
- The Compiler C# PM/VB Dev Lead/C# Test lead ended up owning both languages and eventually the IDE experience for VS2012.
- Compiler has maybe 8 devs (at first) and 6 testers.
- F# stayed pretty much the same, a separate team with one PM working toward its next release in VS2012 but it eventually consolidated its dev lead and test lead roles.
- The Compiler VB PM/C# Dev Lead/VB Test lead ended up owning both compilers for Roslyn.
- The IDE VB PM/C# Dev Lead ended up owning the IDE for both languages for Roslyn.
- There were these cool extra “architect” people on Roslyn.
- The VB Community PM ended up owning both languages.
- VB and C# Language PMs remained separate.
- The VS2012 team decides to do async in both languages and grows significantly.
- The Roslyn IDE might have set out to be unified across both languages pretty early but the compilers were originally designed differently and implemented separately. That’s what drove unification. Their designs were a little different and we observed strengths and weaknesses and different valuable optimizations that each language had come up with in their compilers or interesting tradeoffs that had been traded in opposite directions. And as we were trying to get the performance of the data structures right, we ended up trying both approaches and hybridizing them and eventually it just made more sense to unify the dev teams (they already shared a single dev lead) to get a consistent uber architecture going forward (there are still some differences but they’re very much intrinsic to the languages).
- Compiler test was also unified and this was AMAZINGLY valuable because the test team found so many consistency issues with the APIs between the two languages that drove the design to be better and many differences between the actual language semantics that simply drove understanding of the differences between them.
- Post VS2012
- The VS2012 team does a little work on VS2013, same structure as in VS2012.
- F# gets spun out to another org entirely.
- Post VS2013
- The VS2013 VB/C# experience team joins the “Roslyn” org.
- The VS2013 VB/C# experience team DOES NOT join the Roslyn compiler or IDE teams and becomes something else entirely eventually working on .NET Analyzers.
- Eventually F# rejoins the Roslyn team reforming Managed Languages. At this point they have like 4 engineers total (I think) and no PM (an engineer owned PM tasks). Their numbers shrink and grow and they go through several PMs.
- Eventually Dev and Test are unified across the entire company. For multiple reasons, by this point the unified engineering team (which owns both dev and test functions) is maxed out at maybe 10 non-managers. This is less than the combined size of dev and test before.
- Somewhere in this dedicated community PMs disappear. VB language PM takes over community for both languages.
- Post VS2015
- I own … VB & C# compiler, debugging (EnC, EEs), eventually language, Analyzers, the Roslyn compiler APIs, scripting, interactive (REPL), part of .NET native, part of VSCode, debugging again, analyzers again, and some set of community engagement (not always all of this at once).
- Mads is the C# language PM still, owns a piece of community.
- There was an IDE PM and then there wasn’t technically and then there was but it was a different view of the IDE
- Part of the IDE also split off to own something else.
- The “Compiler” team which was the doubly unified VB and C# engineer (dev and test) team (still ~8-11 people) also began to take over some bits of what the IDE team used to do while the IDE team was taking over everything else in creation.
- Oh, we open sourced everything and that added to what had to be done across the board.
The point of this very long outline is that no divine being ever said “VB and C# ought to be organized this way because it’s good and right and true and best and it would be immoral to organize them differently”. Consolidations mostly just happened in reaction to needs and limitations in the moment and persisted due to inertia. At specific times and in specific areas there was value in the organization but by late in the VS2015 cycle it wasn’t working anymore but we didn’t seriously question it (even me—I thought it was a one-off; I was wrong).
Further, there were like 30 reorganizations and changes to company culture and management at every single level of the hierarchy and across multiple disciplines over this time period with each new manager inheriting this structure from the last probably thinking “That’s how they’re organized because that’s the way they figured they should be”. It’s a historical artifact and nothing more. If it isn’t working anymore (and it hasn’t been) then that structure should have been dumped long ago for something that works.
Meanwhile F# continued to be an autonomous team also mostly because of inertia. They may have reported up through the same managers as the VB/C# compiler team (sometimes) or IDE team (other times) but they remained separate functionally (no pun intended) which meant that no amount of stress on C# specifically could impact F# at all.
“It’s a zero-sum game. Divesting in VB would make C# happen twice as fast!”
This is demonstrably untrue for several reasons. You can certainly organize them in a way that forces them to be a zero-sum game but it’s not essentially the case.
The first reason is…
HUMAN BEINGS ARE NOT FUNGIBLE RESOURCES
It’s not the case that if you have a developer (or other role) that works on one (or two) languages that they can just slide, or more importantly be slid over to another language. I’ve seen this attempted many many times between VB, C#, Python, Ruby, JavaScript, F# in various combinations and in both directions. More often than not that person just leaves the team or the company. It’s not a win for the company because that person isn’t simply replaced with an equally good but more fungible person because HUMAN BEINGS ARE NOT FUNGIBLE RESOURCES. That idea is fantasy. On rare occasion it works but overall, the broader organization just gets smaller and weaker for it because you lose that person’s uniqueness.
The second reason this isn’t true might shock you…
There is a maximum effective team size for any language/layer/component. If you look back at my outline of the history of the team structure, you’ll note that after VS2013 we (the Roslyn VB & C# compiler team) didn’t just absorb the members of the VS2013 VB & C# compiler team. I remember discussing it and the feeling was “the team’s already large enough!”. Even though we had massive scope for where we were in the project adding more people wouldn’t have double the speed or anything and would have slowed things down. Teams grow in scope, not in size. You can get more people by creating a more complex hierarchy but that complexity also reduces efficiency.
And as a personal example, sometime around the middle of 2016 I sincerely tried to leave the PM discipline to become an engineer. There were big changes going on in the PM org. I was in the beginnings of my current nervous breakdown. My depression was spiking. I was super unhappy where I was, I said as much, and I tried to move over to the team that most aligned with my skillset and knowledge to try to manage my stress. I talked to engineering management and I asked several of the Principal-level engineers on the compiler team, with whom I’d worked at that point for 6 years and who had by that point seen many of my check-ins to sign-off on it. All of them were comfortable with me joining the engineering team but I was told by management that the compiler team (then at 10 or 11) was simply too big. The goal for team size is like 6-8. It could not take another person until it attrited 2-3 people and that was it.
My point is, there is a MAXIMUM number of people who can work on the C# compiler effectively and efficiently. Not having people assigned to VB or F# just means having fewer people assigned to those languages and/or fewer people working at Microsoft, it does not produce any automatic boost to the speed at which C# language features can be delivered. If that weren’t the case Microsoft could just hire 50 more compiler majors from Waterloo and everything would be golden. If you want to put 3 people on VB you don’t take them from C# compiler you just add space for 3 new people to the org and fill those positions. Multiple times has someone tried to force people to work on one language or another and they’ve usually failed, and multiple times has the team responsible for the C# compiler rejected new engineers on account of team size. So, this idea that anything has to be done to VB to protect the velocity of the C# language isn’t borne out by the history.
And forcing one team to own scope that was previously owned by 5 teams: [(compiler + ide) * (dev + test) + PM] or even two separate product units is precisely what creates an artificial zero-sum game.
And just importantly, not having a distinct VB team means…
Accountability is impossible
When I came back to Chicago in 2018, I had a huge issue with getting gigabit internet in my apartment. I was extremely angry with Comcast and to this day have not pursued their gigabit internet. I almost took to Twitter I was so mad. But through my incalculable rage I tried to find some productive understanding of what took place and I realized that I was, or at least shouldn’t be enraged with their customer service department. They couldn’t call up the service tech who never showed up. Days later they couldn’t find out if he ever showed up for work again or if he’d had a heart attack in his truck. They couldn’t prioritize sending out a new tech sooner than 2-3 weeks out. They couldn’t waive the requirement for a tech to do the installation to allow me to attempt a self-install. They couldn’t escalate to call in an unscheduled tech for overtime to correct their mistake. All things they should be empowered to do but they couldn’t actually do. And I was mad because I didn’t know that and human beings expect that when they reach out to other human beings for help that those other human beings will visibly try. But they were disempowered customer service. And it caused massive negative sentiment from me toward their customer service and this non-living corporate entity. But I realized my issue wasn’t with the customer service but the organizational decisions which put those people in the position of being disempowered but ostensibly accountable.
A VB.NET community member reached out to me early last year and, frustrated, asked “Why can’t … just say ‘the plan is to do x’ or ‘we’re working on y’ but they can only say this vague aspirational statement?”. They were furious. But when almost every experience, every value-add that you want to provide to your community is distributed across 2 or more teams none of which is a dedicated VB.NET team, you can’t actually be accountable to the community. You can’t have plans. You can’t have roadmaps. You can’t have schedules. You can’t truthfully state that “you’re” working on it or towards it because 3 or 4 nodes in the system have it on a list but you don’t have the influence and specifically the authority to predict the outcome. You don’t have the agility to make adjustments based on feedback on functionality or priorities. You just put inputs into the system and have to hope that the answer that comes out in a few months’ time is one that pleases the community. And if there’s enough stress on the system nothing happens. Everyone team involved gets veto power or every partner team has a management hierarchy which has their own conflicting priorities or their director who needs to sign off on it is out on vacation this week or they just left and we’re waiting for the new person or they need to align with their bosses commitments that just came in or “we’re buried right now because BUILD is coming up” or “Ignite is coming up” or “VS1X.Y update is coming in hot” and these things are always coming up.
And because no one owns the work, no one can rightly account for it to the community. No one can own the story or the message on it because no one controls the story. There’s no story to own. It’s similar to that old saying about parallelism, 9 women can’t have a baby in 1 month. You can’t just average “20% focus on VB.NET” over an organization of hundreds and expect to get much. Except problems.
A few examples:
Some VB developers wanted to use Azure Functions and there weren’t any Azure Function templates in the box so some VB MVP stepped up and made a template. Sounds like a win for VB, Azure, and open source, right? But the process breaks down because the Functions team rightly asks: “Who’s on the hook for maintaining this template moving forward? What if it needs to be changed? What if these static text files that never change need to be converted into a right-to-left YAML format!? We don’t have budget on the schedule!”. So, I say, fine: let’s create a templates repo for community templates similar to what F# has done. But now the question is “Who’s on the hook for maintaining and operating this repo?”. An open source contribution and a sustainable model for open templating going forward dies in committee. And there have been other templates and open source contributions who died similarly.
A developer wants to contribute code to VB.NET: “Who has the time to review his PR, to give him feedback, to work with him to fix the feedback! No time!”. Dies in committee.
We had translated and reviewed samples for Windows 10/UWP ready: “Who’s on the hook for maintaining these 140 samples!? They’re likely going to change and we can’t absorb those costs”. UWP samples die in committee.
The community has repeatedly expressed interest in mobile development using Xamarin. I understand the desire and that the Xamarin team, newly integrated into Microsoft, is doing a lot of stuff. The work for Xamarin.Forms support is not “nothing” but it’s also not insane (it’s mostly just a code generator). So, the Xamarin team kindly offers us access to their repo to simply investigate getting it working (similar to what was done for WP7). But without a dev to start the work and MORE importantly a team that can commit to potentially owning any bug tail or ongoing support costs for that component however small they’re expected to be that very reasonable approach to solving a community pain point can’t move forward even if a tactical strike is possible in the short-term. And no one can fully account for that breakdown.
Ignoring whether that’s actually the best solution for VB developers wanting to explore mobile development, the problem is that no one can rightfully account for that investigation even happening: “Sorry, we decided … well, didn’t decide, but couldn’t do the thing no one could actually committed to doing because there was no one to commit to it in the first place so we couldn’t tell you about it beforehand so now I’m letting you know it didn’t happen because there was no logistical reason for it to happen or way of knowing if it was even possible to begin with. This sentence does not exist.”
And I could cite example after example of language features, tooling features, platform features, open source contributions, samples, templates which aren’t expensive in raw engineering effort but are prohibitively expensive due to the bureaucratic gymnastics necessitated by the lack of an empowered, dedicated, small, agile VB.NET team accountable to the community. And that is how we get where we are today. Not cost. Not practicality. Not philosophy. Not necessity. But failure to adapt. Neglect. Which doesn’t require conspiratorial malice; but that doesn’t matter because at a certain point—the point we’re at right now—any sufficiently advanced negligence is indistinguishable from malice.
In Conclusion
As I said in the beginning, this is not a reaction post or a response to a particular event. It’s something I’ve been working on for a while now in response to a progression. I am posting it now so that as conversations take place about where we are, everyone understands that the current situation is entirely and easily avoidable. If you’re not a VB.NET developer who’s just curious or observing this, understand that nothing reasonable is forcing these negative outcomes. It doesn’t take an army or millions of dollars; it just takes Microsoft getting out of its own way. If you’re a VB.NET community member, know that a better, sustainable, proven alternative is possible and do not be distracted by the addition or absence or promise or request for any particular feature, large or small, any template, any sample, or concession of support. The F# community, a much smaller community than that of VB.NET has (and has always had) a dedicated team working and advocating on their behalf throughout the .NET ecosystem as their main job—their first priority—every day. There is no reason that after 18 years of loyalty, the VB.NET community doesn’t deserve at least that much. Focus your intentions on this goal because regardless of what anyone says the support of a small 3-5 person, agile, empowered, autonomous, passionate, and dedicated VB.NET Team, separate from C#, is the only support that means anything.
-Anthony D. Green