The Road Ahead / Where’s This All Going


Hey all,

It’s been a while since my last post. As promised, I’ve spent the time tending to a variety of personal matters which I neglected during my seclusion producing ModVB Wave 1. One thing I got to do thankfully, was my semi-annual trip to Seattle/Bellevue/Redmond, which I say is for PAX but is really just an excuse to reconnect with my many friends there. I was super happy to see as many of them as I could in that limited time and to catch up with what’s been going on in their lives and catch them up with what’s been going on in mine.

I’m happy to share more of my personal exploits later but most relevant to this post is an individual interaction I had with a friend about my efforts around ModVB. Specifically, he asked (paraphrasing), “Is there are general theme to your future work? Is this all building around one big feature or what?”. Or, in my words, “Where’s this all going?”.

Which is an excellent question. I’m a mysterious hermit who lives in the woods of the South Side of Chicago and periodically I just show up and say some ominous stuff and then disappear. This summer I dropped some language features on you and crawled back into my hole for a bit. All fun, but maybe not as comprehensive as this effort deserves. Fortunately, I have (and have had for years) a massive itinerary (just outline of the language improvements is 10 pages to date) in my head and in OneNote and in Word docs that I’ve been building and following that could easily take a hundred or more of printed pages to detail so I’m not at a total loss for an answer.

It’s just a matter of giving you the forest and not the trees and so I set about sitting about and distilling that roadmap into this post. Hopefully it gives a better idea of the scope of things to come.

The VBest VB that ever VBed

No, seriously, if you take all of the good stuff that VB has been over its life and follow that throughline to its greatest expression in all aspects of the end-to-end experience without compromise, that’s what I’m trying to build. I don’t want there to be any lingering questions of what VB could have been if only things had been different. I want to build that thing, or at least my interpretation of that thing based on decades of experience using it, analyzing it, designing it, and communicating with other community members about their experiences, desires, and needs while using it too.

Still have questions about what that means or what it looks like? Well, over the next 1-2 years of building it I expect to design, discuss, initiate, or produce enough artifacts that you don’t. That’s the journey. Now let’s get a little more concrete about 3 layers being built.

  1. Core Language Experience: I want to build a massive, robust extension and modification of the vanilla VB.NET language and tooling that evolves, modernizes, and refines the language for current and future enthusiasts in a self-consistent manner.
  2. Extended Tools & Experiences: I want to build additional tools to enhance the VB experience beyond the core modified language to support certain platforms, technologies, and scenarios.
  3. Community: I want to build a self-sustaining community of VB enthusiasts around this modernized end-to-end experience.

These three layers make up the VB.NET UX I’m trying to build: language, tools, community.

Building for the enthusiast, not the user

Notice that I keep using the word enthusiast rather than user. Anyone can be a user just by using a thing. They don’t have to like or love the thing or have any particular attachment to the thing. They may even hate the thing. I’m not talking about those people. There is no victory to be claimed in planning anything around an audience that isn’t at some level already bought-in or capable of buying in to what you’re building. A VB enthusiast should feel like a kid of Christmas morning about this endeavor: they may not know what’s in the giftwrapped boxes but they’re excited. I want to justify and grow that excitement. If you don’t care, that’s fine, you just probably shouldn’t be reading my blog and I definitely shouldn’t be trying to court your approval. Personally, I believe it would be healthiest for the VB community to as much as practical consist of enthusiasts rather than users. This doesn’t mean they aren’t “real developers” or that their projects aren’t “real apps” and it doesn’t mean (primarily) people who aren’t getting paid to build software, but that the ones who are getting paid are enthusiastic to come into work and work in VB every day.

For a long time due to its popularity with businesses VB has accrued all sorts of users, including an unfortunate lot who were forced to use by circumstance. The problem is that group produces an awful lot of noise when planning and prioritizing feature work because ultimately they want to use something else entirely and they want VB to just become that other thing. I want VB to be a language of choice, not force, and to cultivate a community of folks who choose VB because the “Spirit of VB” resonates with them and empowers them. I can wax philosophical about the “Spirit of VB” for pages (and I know I must do so soon) but for the sake of some brevity I’m going to try to keep this post a little more concrete.

Breaking down the VB experience

Back in my Microsoft days, once a year during MVP Summit I’d get a chance to meet with the brightest minds in the VB community (diehard enthusiasts and absolute professional badasses) and present an early preview of what we were working on and get their feedback and hear their pain points from real world projects that they wanted solved in the next version (hopefully). In the later years, as lead language designer, it fell on me to not only participate in the summit (which I loved doing) but to present Microsoft’s side of the conversation for VB. I took to a format that I styled the “State of the Language Address” whereby I broke the VB experience down into four areas of concern for the VB audience:

  • Platforms & Technologies
  • Language & Runtime
  • IDE & Tooling
  • Community & Content

For each area we’d summarize the feedback we’d heard from the community over time, how we’d reacted to their feedback, and what our next plans were for the area. Having found this a useful structure in the past, I will frame the rest of this post around these four areas. Typically platforms & technologies would be the top-of-mind area for MVPs and I still think it’s the most impactful but for this post I’m going to lead with the language because a key priority for my language modding efforts is investing in features which enable broader platform reach, particularly in Wave 2.

Language & Runtime

As I mentioned earlier, I have a 10-page outline of just the language modifications I intend to produce over the next… 18-months(?) or so. Some are bigger, most are small, all are doable and I believe genuinely in the spirit of the VB language; they fit with the values VB has articulated thus far and will be designed and added in a manner which is natural and self-consistent.

Originally, I broke this outline into 4 major categories:

  • Modernization—New functionality added to service modern scenarios or modern platforms. E.g. XAML Literals, JSON literals/pattern matching.
  • Evolution—Enhancements that extend an existing construct to its logical “next step”, e.g. query operators in `For Each` loops.
  • Streamlining—Reduction and in some cases elimination of boilerplate/ceremony in common scenarios or polishing “rough edges” in a scenario, usually through some addition to make the language more self-consistent, e.g. type-inference improvements.
  • Bugfixes—Changes made purely for self-consistency, correctness, interoperability, or code-optimization, e.g. new implicit line continuation, VB runtime performance improvements.

In addition to language changes I intend to release a modded VB runtime with new support types and other enhancements as the language evolves. For the time-being I’ve baked these changes into projects compiled using ModVB as embedded code a la VBCore.

Those categories still hold true but I’ve since found it more practical for communicating with my readers to describe them in terms of time, specifically 6 or more “waves” each with a particular theme. Each wave is not exhaustive—every conceivable feature under a given theme won’t be added in that wave. Rather, I have prioritized certain features in that them around the need for feedback, the risk of adding them, size (time), and impact (the usual suspects). I’ve summarized the first 5 waves and beyond below.

Wave 1 – JSON

The first wave released this summer and was centered around JSON Literals and Pattern Matching.

JSON Literals & Pattern Matching

This wave was intended to be short and to prove out the possibility of shipping language features via VSIX and NuGet at all. It is but a prelude—an amuse-bouche—to the full scope of language enhancements that are planned. In fact, it’s not even the complete story I imagine for JSON or pattern matching, both of which have deeper integrations on the backlog. Having said that, it was successful at its purpose and an update based on feedback should be released before Wave 2.

Wave 2 – XML

It is not my intent to be hyperbolic when I say this. Wave 2 contains the most important features that could ever be added to VB.NET. Seriously, if just these features were added and nothing else it would constitute a full step forward for the language over where we are now, though fortunately we won’t have to make that trade. The core feature of the wave are enhanced XML literals (every day I wrestle with calling it XAML literals though it just as well could be called HTML literals too), a feature I prototyped back in 2019 but am now rebuilding The Right Way™ along with the support feature of top-level code.

As demonstrated in these videos, these two features combined create a story for VB.NET building modern apps for web and mobile using ASP.NET Core and Xamarin.Forms .NET MAUI and untold other DSLs for other technologies.

ASP.NET Core Web Programming with VB.NET Pattern-Based XML Literals
Client-Side VB.NET in Browser with VB.NET Pattern-Based XML Literals
Cross-Platform Mobile Development with VB.NET Pattern-Based XML Literals

I do have work to do to account for the changes from Xamarin.Forms to .NET MAUI though from preliminary investigation MAUI is an evolution of Xamarin.Forms and adheres to the same design patterns. Libraries implementing the XML patterns for web and MAUI are being developed in lockstep with the patterns themselves. I have not had a chance to deep dive into the story for Blazor but the F# technology Bolero which enables F# developers to make use of Blazor tech to bring F# to the client-side gives me confidence that the system is open enough for VB to also benefit from Blazor, provided the right experience in the language. Alternately (or additionally), the OpenSilver project (which provides a plugin-free open implementation of Silverlight based on modern web tech) may also be a great opportunity to bring rich modern web application development to VB.NET!

This is the approach F# uses to reach new platforms and it works. I’m determined to use it to bring a high quality web and mobile story to VB.NET as part of the ModVB project.

I believe this work, especially when combined with the Roslyn scripting API (which will one day be completed for VB if only in this mod) will unlock the ability to create UI previewers/designers and other tools.

A detailed deep-dive into the design changes I’ve made since I wrote those initial prototypes as well as the libraries I’m writing alongside the features as part of Wave 2 to support web development and .NET MAUI will be the topic of a future post.

Wave 2 is planned for release around December 2022.

Wave 3 – Productivity

A grab bag of 4-7 productivity features I’ve been itching to add and demonstrating remarkable self-control by not adding. They’re all small to medium in size compared to waves 1 and 2 and will likely be released one at a time. I simply need to get these things out of my head.

Wave 3 doesn’t have a forecasted delivery window though waves are intended to be 2-3 months in duration.

Wave 4 – Async

I vacillate back and forth on whether this and wave 5 should be swapped. Today it comes first because the LINQ related features are all pretty straightforward and making any changes with Async deserves plenty of bake time to ferret out bugs and react to feedback. There are several missing pieces to VB’s Async story, e.g. an `Await Each` construct, `Async Iterator` methods, `Await` in `Catch` and `Finally` blocks, and more. Not every feature will be included in Wave 4 for time reasons but by the v1.0 release of ModVB I plan to address them all.

Wave 4 is after Wave 3.

Wave 5 – LINQ

There are no surprises in Wave 5. It’ll include deeper integration of LINQ into the language and revisiting several features added as part of the initial LINQ release way back in 2008. For example:

  • Integrating query operators into the For Each loop.
Extending VB.NET For Each loop with LINQ comprehension operators
  • More expressivity in object member and collection initializers
  • Range expressions
  • Possibly more query comprehensions

Wave 5 is after Wave 4.

Wave 6 and Beyond

OK, so technically there isn’t a “Wave 6” so much as everything else is post Wave 5. This is where the less glamourous or most difficult work goes. Bug fixes. Optimizations. And one or two … high-cost/risk features like Nullable Reference Types live. This is the long tail of quality-of-life features, advanced features, and edge cases (many of them long requested by the VB community) that will easily eat up 60-80% of the time on the project. I may try to plan several formal waves or I might just loop through the list picking off low-hanging fruit until it’s all done.

So, for example, for ever VB users have been asking for Modules that don’t automatically promote their members to their parent namespace. I absolutely will address this request after over a decade of fielding complaints about it. It’s not super impactful or risky, so it’s just “on the list”.

A Note on Language Stability: My plan isn’t to release a million features every year. Many of the features alluded to above are long overdue and if I’d had my way would have been completed years ago. For this reason, I’ve built up something of a backlog. But after the v1.0 release of ModVB, I expect language iteration to comparatively slow because it’s simply not necessary to shatter the earth with every release of a language. I intend to code in VB.NET until they pry it from my cold dead hands. But I don’t intend to try to re-invent the fundamentals of programming every release in order to keep up with any other language; every major release won’t be Generics, LINQ, Async, or even dynamic. I truly believe that with the set of features I’ve collected VB.NET will be in an incredible spot as a language and will need relatively few new general purpose features. Instead, I intend to pivot to more evolution on the end-to-end tooling of VB.NET to recapture as much of that magic that’s always kept the language ahead of the pack. I say all of this not to dampen expectations; this isn’t a policy thing and I’m happy to be proven wrong. Rather, I say this to give the more cautious developers assurances that I’m not going nuts and throwing everything and the kitchen sink into the language. It’s not going to look unrecognizable when ModVB v1.0 releases and I intend to keep the pace of change sustainable after that.

Platforms & Technologies

As mentioned above, my immediate concern for Wave 2 is unblocking ASP.NET Core and .NET MAUI. In addition to the language features described in Wave 2 I will be shipping runtime extension libraries for .NET MAUI as well as a brand new VB-targeted web programming library and several templates for using both. Blazor will hopefully come at a future date. I might do a proof of concept for a web UI designer sometime after Wave 2 is complete but I don’t expect any serious pursuit of such a tool until after v1.0 particularly as this may require completion of the long in limbo Roslyn-based VB.NET Scripting engine.

Other technologies such as Unity are interesting to me because they’re interesting to VB enthusiasts though it isn’t an urgent concern; happy to collaborate with anyone who’s more fluent in that space about their needs or opportunities to light something up here.

IDE & Tooling

In addition to the core support for new language features in the VS editor I also plan a slate of VS extensions to supplement the VB experience. In fact, I’ve already started development on one that’s near readiness for a release but I’m pausing work on it while I finish Wave 2.

I’m very interested in partnering with anyone who has the know how of how to plug ModVB into a .NET Interactive/Polyglot Notebook.

Long term (as we approach ModVB v1.0 release—late 2023/early 2024) I expect to pivot toward looking for a cross-platform IDE for the modified VB language. The open-source F# Ionide and C# OmniSharp plugins for VSCode should provide excellent instruction for where to begin here and again I’d love to collaborate with anyone with expertise and interest in this area.

Community & Content

As I mentioned above, my endeavor is not merely to create a modified version of the VB.NET language but a revitalized VB.NET community around it. To that end, in early 2023 I will be launching a new community web site to promote and educate VB enthusiasts about a variety of topics, including this and other mods, news, and other tools in the broader VB.NET ecosystem. I would like to make this new site a gathering place for VB content from other community members with an aggregate blog, forums, and technical articles. The big question now is whether to roll something out based on an existing web hosting provider like WordPress or roll my own using the ASP.NET Core support I’m building in Wave 2.

Wrap up

I’m excited to be working to bring new capabilities to the community, not least of all because I love VB.NET and absolutely want to use it on all of my future projects, personal and professional. I’d love to talk more often and in greater detail about the design process I’m following but it’s hard. My (unsustainable) process has thus far been to quite literally seclude myself from the world and focus (and re-focus) myself relentlessly toward the next goal neglecting everything else in my life.

When I wrote “An Exhausting List of Differences Between VB.NET & C#” I literally hermited myself in my apartment for 5 or 6 straight weeks where I did little but eat and write. I didn’t even do laundry or clean my home. The journey to Wave 1 this summer was very similar; I was literally buried in trash recycling by the end of it. I have no work-life balance, I think, because of my mental health struggles. I also have mental health struggles because I have no work-life balance. To do this project I have to wear every hat in the development process from PM/dev/test to marketing and docs. I have the experience to wear those hats but not all at once and switching modes is especially challenging. It can just be so hard to focus and stay on task and I build up so much guilt and self-loathing about not being faster or more consistent or more communicative. So often I just want to crawl into a hole and stay there. But when I muster the strength to crawl out of that hole all I can think about is all the wonderful stuff I want to build with and for VB.NET. Even in my depressed moments that’s what I’m thinking about. I realize, this is my life’s work.

I bring that all up to say, this week after dodging it for 30+ years I was diagnosed with ADHD and have been prescribed some meds to help me focus. I’m really really hoping this new chapter in my mental health journey will let me find more balance and that will be good for me and for you all. Thanks for your support and continued patience.

Look out for…

  • Wave 1 Update 1 soon
  • Wave 2 circa December 2022
  • More design discussions from me sprinkled throughout


Everything we need is doable. Much of it has been done before. There will come a time for almost everything. We may be taking steps back but when we leap forward I believe we’ll be in a much stronger position than ever before.

The answer to “Where’s this all going?” is… Everywhere.



ModVB “Wave 1”—JSON Literals & Pattern Matching

Thanks everyone for your patience these past two months. I had to learn and do a lot to bring you this first release so I hope you find the wait was worth it. Today I’m launching an alpha of my mod, imaginatively titled “ModVB”. Installation instructions here for how you can safely install it to use JSON Literals and Pattern Matching right now! (Spoiler: You install a VSIX and reference a NuGet; that’s it)

This post is about the new features included in “Wave 1”. These are not prototypes like in my previous videos. Prototypes are quickly implemented to demonstrate the utility of one or few narrow scenarios taking whatever shortcuts possible to get to something that “works” (enough to solicit feedback) as quickly as possible. But the functionality in my mod is done “The Right Way”™ and should be extremely stable (crashes or freezes should be rare; please report immediately) and pretty close to what could be the final design. Read more about them below.

I’ve talked about JSON literals in previous posts, so I’ll start off with the newest feature on the block, pattern matching.

Pattern Matching

With respect to JSON, pattern matching is essentially the opposite of a JSON literal. Whereas a literal makes it easy to construct a JSON object in a way that preserves and reflects the structure of the JSON you’re trying to create, pattern matching allows you to deconstruct JSON in a way that likewise preserves and reflects the JSON’s structure.


As of the time of this writing, here are the patterns that are supported by the Select Case ShapeOf syntax:

In all cases, null-ness may be “runtime extension defined” (see “Runtime Extensions & API Compatibility” below). This just means the compiler calls a helper method to determine whether something is true or not rather than purely CLR semantics. This is necessary because, for example, a JValue object is not null but represents the concept of null in the JSON space. Likewise, a JsonElement structure isn’t nullable but may still represent a null value.

The JSON Object Pattern

  "<name 1>": <pattern>,
  "<name 2>": <pattern>,

Matches a value if it: is not null, represents a JSON object (as defined by runtime extension), has the non-optional members named, and each member found matches its corresponding pattern, recursively.

This is evaluated top to bottom (depth first) so the entire first member and its pattern are evaluated before the second member is searched for.

This is not exhaustive; the JSON object may include more members than the ones listed and still match.

May be marked optional by placing a question mark ? after the closing brace. In which case, the pattern will also match a null value, i.e. the value is null OR matches the above criteria.

An individual name-value sub-pattern can also be marked optional:

Case {
  "firstName": required,
  "middleName"?: optional

In this example pattern requires that a firstName be included in the JSON payload but the middleName may not be present at all. This is subtly distinct from being present but null. Some JSON producers may not include null values by default. This syntax provides an easy way of consuming JSON from these producers in a way that treats an omitted value the same as one that is explicitly null.

The Empty JSON Object Pattern


Matches a value if it: is not null, represents a JSON object, and that object has no members.

Unlike the non-empty JSON Object Pattern, this pattern is exhaustive.

May be marked optional by placing a question mark ? after the closing brace. In which case, the pattern will match a value that is null or is an empty JSON object.

The JSON Array Pattern


Matches a value if it: is not null, represents a JSON array (as defined by runtime extension), that array has at least as many elements as listed, and each of the first n elements matches its corresponding pattern, recursively.

This is evaluated top to bottom (depth first) so the entire first element and its pattern are evaluated before the second element is searched for.

This is not exhaustive; the JSON array may include more elements than the ones listed and still match.

May be marked optional by placing a question mark ? after the closing bracket. In which case, the pattern will also match a null value, i.e. the value is null OR matches the above criteria.

The Empty JSON Array Pattern


Matches a value if it: is not null, represents a JSON array, and that array has no elements.

Unlike the non-empty JSON Array Pattern, this pattern is exhaustive.

May be marked optional by placing a question mark ? after the closing bracket. In which case, the pattern will match a value that is null or is an empty JSON array.

The Constant Value Pattern

<constant literal>

This can be any constant literal in VB (including Date and Decimal values and Nothing) or the JSON constants true, false, or null. These JSON constants behave exactly as VB True, False, and Nothing respectively.

Matches a value if it (for constants other than Nothing or null): is not null, is convertible to the type of the constant, and after conversion has a value equal to that of the constant.

If constant is the literal Nothing or null, will match if the value is null.

May be marked optional by placing a question mark ? after the literal. In which case, the pattern will match a value that is null or equal to the constant.

The Variable Declaration Pattern

<identifier> As <Type>

Captures a value in a variable. The As <Type> clause may be omitted.

Matches a value if it: is not null and is convertible to the specified type. If the type is omitted the pattern will match any non-null value and the type of the variable is inferred from the type of the value.

Convertibility considers reference conversions and intrinsic language conversions as well as runtime extension defined conversions. In the absence of one of these a conversion may also be attempted if the value represents a String and the specified type defines a TryParse method or the specified type is an Enum type, in which case the pattern will succeed if a call to TryParse succeeds.

May be marked optional by placing a question mark ? after the type. If the type is omitted, the question mark ? may be placed after the identifier. In either case the pattern will match all values null or otherwise.

A note on optional patterns

When a JSON object pattern, one of its name-value subpatterns, or a JSON array pattern is marked optional, any variable declaration patterns within are necessarily nullable; if the parent pattern matches a null value these variables will also be initialized to null.

More to come

More patterns will be added later, as well as an expression version of the ShapeOf operator.

Runtime Extensions & API Compatibility

Both pattern matching and JSON literals are pattern-based, in the same way as LINQ and the For Each loop; they aren’t tied to any particular library or set of types. Instead, the implementations of these features look for helper types in a special Extensions namespace, decorated with the correct attributes, and having methods with certain names and shapes. The indirectness of that sentence reflects the levels of indirection built into the compiler to achieve this flexibility. You don’t need to worry about any of that other than that you should reference particular NuGet packages from the ModVB NuGet feed when you want to use these features with the corresponding APIs.

If you want to use JSON literals and/or pattern matching with:

  • Newtonsoft.Json.Linq types (JObject/JArray/JContainer/JValue/JToken/JProperty)

Reference package: ModVB.Runtime.Extensions.NewtonsoftJson

  • System.Text.Json types (JsonElement/JsonProperty) or System.Text.Json.Nodes types (JsonObject/JsonArray/JsonValue/JsonNode)

Reference package: ModVB.Runtime.Extensions.SystemTextJson

More such libraries will be released for other JSON libraries in the coming weeks.

It’s worth noting that these are not mutually exclusive. You can reference as many extensions as are applicable to your project without conflict. Pattern matching only pays attention to the extensions required for the type being matched against and JSON literals are target-typed (more on that below).

JSON Literals

I talked about JSON literals in this blog post and this blog post. Please check them out. The scenarios still apply, and the behavior is still the same except the JSON literals in this mod are far beyond prototype quality. There are two new behaviors as well: flattening and target typing.


The properties of objA are “flattened” into objB (objA isn’t changed, of course). If instead of adding another object directly you add e.g. an IEnumerable(Of JObject), each JObject is flattened into the result in sequence:

The query yields a bunch of objects, but those objects are all flattened into the one outer object. This is a convenience feature particularly in LINQ as it allows you to yield a list of objects as a collection of properties, without requiring either an explicit syntax for a name-value pair or instantiating JProperty explicitly.


JSON Object expressions and JSON Array expressions are target-typed. Meaning, if you for example, assign a JSON literal expression to a variable or pass one as an argument to a parameter of type JObject/JArray (or one of their base types), the expression will construct that type. You can also use an explicit cast to determine the type of the resultant object.

Default JSON Object and Array types

In contexts where no target-type is available such as when using local or method type inference, or contests where the expression is being converted to Object, the expression will be evaluated as if it has the default JSON Object or Array type.

This lets you have a project that references multiple JSON APIs but doesn’t require explicit casts everywhere if one API is preferred. So, if for example, you have a project that predominantly uses the Newtonsoft JSON.NET types but you need to interoperate with APIs that work with the new System.Text.Json.Nodes types you would probably set your default object and array types to JObject and JArray and use target-typing in those specific times when you need to construct a JsonObject or JsonArray.

The default JSON Object type can be configured by setting the DEFAULT_JSON_OBJECT_TYPE preprocessor constant in your project settings to the fully qualified name of the type you wish to use. Likewise to set the default JSON Array type set the DEFAULT_JSON_ARRAY_TYPE constant.

If you didn’t know that VB pre-processing constants can have actual values—they can. A fact that I’m going to exploit heavily in future releases to avoid more cumbersome changes to MSBuild or the project system. Besides, after decades of being in the language, it’s time that capability start pulling its weight!

A few more notes: If this setting isn’t in your project settings the compiler defaults to the JSON.NET types because 2.17B downloads can’t be wrong and System.Text.Json.Nodes only exists in .NET 6 and later. I am thinking about making this default change based on whether you’re targeting .NET 6 and up or .NET Framework though.

The default JSON Object and Array types do not impact pattern matching except when trying to use an JSON object or array pattern against a value of certain types like Object or interfaces. In that situation you’re assumed to be testing the reference against the default object or array type and so the pattern will fail if the value is an object-typed reference to a different JSON library’s object or array type. To solve this you have to cast the value to at least the root of the correct type hierarchy (e.g. JToken/JsonNode) to let the compiler pick up the correct extensions.

Why Not Just Use Serialization?

On a previous post one or more commenters asked (paraphrased), “Why bother with this when everybody uses serialization?”

Well, for starters everyone isn’t using serialization. Only people who are using serialization NOW are using serialization. There are developers who aren’t exploring the power of the cloud or NoSQL database techniques at all and maybe this way of doing things makes it more appealing or more productive for them to do so, myself included.

I love types, I do. But honestly I’m a little fatigued on superfluous data transfer types that only exist to be serialized/deserialized. I had a project recently that was inundated with these anemic domain “models” for the sake of “doing it right” even in situations where no class was really needed.

For example, we had this dashboard API, part of which returned data to be rendered in the browser by a client-side JavaScript charting library in a SPA. There was absolutely NO value in trying to recreate the API of the JavaScript library. Ultimately, to the chagrin of my peers, I just constructed a returned a bunch of JObjects and JArrays matching what the charting library expected rather that “pretending” to build some rich type safe object model that was just going to get stringified immediately.

I worked on the Roslyn APIs for over half a decade; I believe in the benefits of types. But I also spent a good chunk of my career chasing after the ideal of “persistence ignorance”. The idea that domain objects are pure and free floating abstractions that are the true model of all software and the fact that objects happen to get saved to databases, or happen to get saved to the file system, or happen to get sent back and forth over the network via services is just an implementation detail. And in plenty of cases that’s absolutely true.

But there are also cases where the goal is to talk to a REST service you don’t own, or to manipulate some JSON in a database. If the currency of truth in an operation is JSON, it’s not the implementation detail, your POCOs are. The JSON is the whole point. Serialization classes are just something I would have done to make the SPA’s JavaScript charting library fit into a .NET world; I didn’t own that model.

And besides, if it’s true that serialization is the be all and end all of dealing with JSON no one would make types like those in the System.Text.Json.Nodes or Newtonsoft.Json.Linq namespaces. They exist both for convenience and because sometimes you’re working with highly heterogenous, schema-less data where the impedience mismatch between your data and the OOP world imposes a cost you deem not worth paying.

Another example that comes to mind is DataTables.

Wait, hear me out!

We’ve had typed DataSets in .NET for almost 2 decades now. Strongly typed. IntelliSense. All that. We’ve also had popular ORMs on .NET for almost as long. Yet often when I look on Facebook or a forum, there I see people using untyped datasets. Why?

My hypothesis is that when thinking about databases DataSets and DataTables are this remarkably minimal abstraction over the natural domain of a relational result set/table/row/column. They are to databases what HTML and CSS are to Web UI (as contrasted with the abstractions of Web Forms). Some people just like that thin abstraction, or need it, or benefit from it. My hypothesis is that untyped JSON objects are the analogous abstraction for the Cloud and NoSQL and that providing them will bring more developers to modern paradigms beyond the ones who are doing it now.

And then there are interactive and exploratory scenarios… if I’m in an interactive or exploratory context (and as part of this modding endeavor I plan to pursue more interactive and scripting contexts for VB.NET) I don’t want to jump through all the hoops of serialization to explore an API or a database. This convenience empowers me at different phases of my project or different activities on a project where speed and ease (for me) are paramount.

Sometimes when I’m mocking out a UI I don’t make any classes, I just whip out some XML literals and mock up an entire data model to bind to in XAML because that’s the fastest way to get a prototype going. And don’t even get me started on all of these reporting-only small classes that only exist for one UI or another, no domain purpose: OrderSlim, OrderSearchResult, OrderSummary, OrderInfo, OrderViewOnPage4. I’m very interested in exploring CQRS and I think raw JSON is a perfect fit for a lot of the Query responsibilities instead of all those fake domain objects.

In short, after all that rambling, there are tradeoffs and these features exist on a spectrum, and I’m making them to give the language more versatility and appeal to a broader set of users and scenarios. Serialization still cool.

What’s Next?

Why, “Wave 2” of course! It won’t be a big secret like “Wave 1”, I’m going to be upfront with what’s going to be in it but I need a little recovery time before getting started on that and to tend to other matters in my life which have gone neglected these last two months. I also plan to blog a little more about the contents of “Wave 1” and release a couple more NuGet packages with JSON literal and pattern matching support for a few more JSON APIs such as MongoDB and Oracle NoSQL.

  • Read this post for instructions on how to install ModVB for yourself
  • Try out the mod—do anything you’re interested in doing with the new features
  • File bugs at
  • Feedback and discussion on my blog, your blog, Twitter, YouTube, or wherever you hang out with other VB.NET enthusiasts!
  • Don’t forget to SHARE!

Introducing ModVB—A free, independently-created “mod” for VB.NET that gives you new features just by installing a VSIX…


…and referencing a NuGet package. That’s it. That’s the whole thing.

As mentioned in my previous post, I think modding represents one path forward for my favorite programming language, VB.NET. So, I’ve created my own mod to help me explore the years of ideas I’ve had for VB and to share them with others!


ModVB is more than just an unimaginative name. Yes, it means “modified”. But it also means modern. And modulo (with respect to).

And the mathematically inclined will note that: (VB + ModVB) Mod VB = ModVB

(Assuming ModVB is less than 2x VB, which it is). You see, I really did put a lot of thought into this!

The first wave of new functionality is introduced in the very next post on this blog: ModVB “Wave 1”—JSON Literals & Pattern Matching. Please check out the post and the accompanying video for more details on what you can do with this first pre-release version. I’ve labeled it an alpha because it’s very early in the development of the mod and semantics will likely change. That said, I’ve built it for stability so crashes or hangs should be very few (and please report them if you find them so I can fix them ASAP).

Look forward to future posts from me about how you can make and distribute mods of your own!

About the Developer (Me)

A man in a suit (auto-generated)

My name is Anthony D. Green (he/his/him). I’m a 37-year-old VB developer from Chicago, IL, USA. I previously worked at Microsoft for 8 years on the Managed Languages team. For most of that time I was the program manager for the Roslyn compilers; communicating with customers and working with Microsoft architects, developers, and testers on designing and implementing the VB.NET and C# compilers in VB and C# respectively as well as a large part of the Roslyn APIs that power the VB and C# IDE experience inside Visual Studio.

For my entire Microsoft career, I served as a language designer on the VB language design team, which I led for 2 years, during which I also served ex officio on the C# language design team. Both before and after my time at Microsoft I’ve worked as a software architect consultant in Chicago for a total of 5 years, mostly working with .NET and other Microsoft technologies.

VB.NET is my passion and I’ve enjoyed working with it both as my profession and as a hobby, starting with VB4 when I was just 13-years-old. I’m building this mod mainly for myself because I want to see the language and experience evolve to their limits but I hope others will get benefit from it as well because I really want to see the VB.NET community grow and flourish. To everyone who chooses to join me on this journey, thank you for trying my mod!

Installation Instructions

This process is easy solely thanks to the heroic efforts of the Roslyn infrastructure teams throughout the years. I just implement the features; they made it possible for me to share them with you.


  • Visual Studio 2022 (any edition, including Community) and VS2022 Update 17.3.1


  1. Launch Visual Studio 2022 in a new hive

This creates an isolated configuration of Visual Studio 2022 that you can install the mod into. ModVB is currently in pre-release and installing into a separate hive means you can always launch Visual Studio 2022 normally if you encounter bugs or blocking issues or simply want to return to the behavior of “Vanilla” VB.NET. Even when the mod eventually releases you may wish to use separate hives to maintain this flexibility.

  • Open the Visual Studio 2022 Developer Command prompt (Start > “Dev…”)
    • Enter the command `devenv /rootSuffix ModVB`
  • Click “Continue without code” (bottom right)

You can always confirm when you’re using the ModVB hive because “MODVB” will appear in the upper right corner of Visual Studio 2022 when you’re using that hive.

  1. Add the ModVB MyGet VSIX feed to Visual Studio as an additional VSIX gallery
    • On the menu, open “Extensions > Manage Extensions”
    • Click “Change your settings for Extensions” (bottom left)
  • Click “Apply” and then “OK”
  1. Download and install the ModVB Language Services extension
    • On the menu, open “Extensions > Manage Extensions”
    • On the left, select Online > ModVB
    • Download the “ModVB Language Services (Built with Roslyn)” extension
  • Close Visual Studio 2022
    • The VSIX Installer will open. Follow the instructions in the installer to complete the installation
    • Re-launch the Visual Studio 2022 ModVB hive by entering `devenv /rootSuffix ModVB` at the Developer Command Prompt. You may wish to create a separate Windows shortcut with this option for convenience.

Installing the language services VSIX enables any new or modded IDE experiences inside of Visual Studio 2022, including the IDE experiences for new language features such as IntelliSense, syntax highlighting, and code actions. However, for building projects using new or modded language features and semantics you’ll need to reference the ModVB compiler from those projects. This also enables those projects to build as part of your CI/CD process on build servers which won’t have Visual Studio 2022 or the ModVB Language Services VSIX installed.

  1. Add the ModVB MyGet NuGet feed to Visual Studio as an additional NuGet package source
    • On the menu, open “Tools > NuGet Package Manager > Package Manager Settings”
    • On the left, select “NuGet Package Manager > Package Sources”
  • Click “Update” and then “OK”
  1. Install the ModVB.Compilers.Toolset package to any projects you want to compile using new language features
    • On the menu, open “Project > Manage NuGet Packages…”
    • At the top, select Browse
    • Select the ModVB package source in the drop down at the top right
      • Make sure “Include prerelease” is checked (next to search box)
    • Select “ModVB.Compilers.Toolset” on the left
  • Click “Install” on the right

Congrats! Your project will now build with the ModVB compiler and have access to new features for VB.NET. Of course, if you’re not using these features the behavior of building will be exactly the same as before. Remember to add this package to any additional projects where you wish to use new functionality. Happy coding!

Next steps

  • Read this post detailing the new features in “Wave 1” of the ModVB alpha
  • Try out the mod—do anything you’re interested in doing with the new features
  • File bugs at
  • Feedback and discussion on my blog, your blog, Twitter, YouTube, or wherever you hang out with other VB.NET enthusiasts!
  • Don’t forget to SHARE!

Checking in (Wave 1) Update 2 SP4 R3

This is waaaay overdue, I know. So here’s what happened. That little bit of scope creep I decided to take basically reset the whole sprint. I didn’t have to throw away any of the code but it did expose every assumption that was in code and multiplied my testing matrix by like 4-5x because I’m supporting many more use cases than before. I’d say the effort has been 40% new code, 60% testing.

Also I took a week off due to prior commitments away from my keyboard with friends and family.

So why did I decide to increase scope so late? Precisely because of how disruptive this change has been. If I didn’t do it now I’d be compelled to do it immediately after Wave 1 and it would interfere with waves 2-3 which are entirely different feature areas. All of the assumptions would be more entrenched and there was a good risk of shipping things that were wrong in subtle little ways–I definitely had to withdraw certain functionality that was overly specific. And aside from the “happy path” experience which was originally designed, I had to design and test a whole “graceful failure” path. This is essential work for tooling anyone else is going to use. Nothing has been wasted in this effort.

So where are we at? I’m writing more tests. I admit I’m not nearly as fast a tester as I am a dev and switching hats makes me miss the days of having dedicated QA. I’m fixing minor bugs. Don’t have an exact release date but “soon” ™.



P.S. I’m going to publish what’s in Wave 2 BEFORE it starts. I appreciate that the suspense is problematic.

Checking in (Wave 1) UPDATE

After due consideration I’ve decided to delay today’s release to next week. I’m concerned that rushing testing/stabilization will only hurt … everybody so I’m giving it more “bake time”. Additionally, I’ve relented on some critical (minor) scope creep in the same areas being tested/stabilized now; it’s beneficial for a lot of reasons to do it now instead of as part of Wave 2. This new work is thematically consistent with what I had planned to release today, very important to the broad utility of that feature set, was half-implemented already–it was designed for from the beginning, and I’m kind of excited by it in an ice cream on top of pie kind of way.



Checking in (Wave 1)

Just leaving a quick note for readers curious about my progress. In my last post I said I was working on an initial preview release of my mod with some new features. I’ve basically been heads down coding since I wrote that post and I finally punched through and end-to-end spike of an initial set of use cases.

I pull up a video of this scene literally any time I get any non-trivial amount of code to run as expected.

Now comes the fun part, rigorous automated testing of 100+ test cases and more bug fixing. Making sure that not only do things work the way I expect where I expect but that they don’t work in other ways where I don’t expect and that everything that does work does so for the right reason(s) and that nothing crashes. The bar is far higher for even a preview of a mod than for my past prototypes so I have to really go at things with hard pipe-hitting, blowtorch- and pliers-wielding permutations now.

This bug bashing is what I’m up to for the next 48-hours then on Friday (just in time for the weekend) I plan to publish some bits to play with. I also have to script and record a brief video explaining what to actually play with.

Fingers crossed! We’ve got a long road ahead of us and this first step is tremendously important. See you soon!


An Alternate Path


It’s funny how a tiny bit of feedback can change the nature of a post. I had originally planned to write about modding in the gaming community and the impressive accomplishments independent developers and enthusiasts have had in expanding and extending the experience of games, sometimes vastly, beyond the intent of the original creators (e.g. Breath of the Wild: Second Wind). In some cases, games have come to be defined by their modding culture (e.g. Skyrim) and in others mods have taken on a life of their own to become products that arguably overshadow their base games (e.g. Counter-Strike) or even spawn new genres (e.g. Dota). I had some anecdotes about the first software I ever “modded” (Mavis Beacon Teaches Typing) or twiddling with QBasic games’ source code as a young teen.

That said, I got a bit of feedback after my last post that something maybe a little broader (yet also more direct and specific) would probably be better received so I’m going to try to fumble through distilling at least some of two years of thought and research and—yes, planning—into an elevator pitch. Well, maybe not that short, but still a challenge of brevity.

For starters, let me set a few expectations. Firstly, what I’m proposing is without a doubt going to be a pain in the ass, at first at least. It’s a lot of work. When I say a community-driven­­ path forward, I don’t mean a community-accentuated path forward. I don’t mean community-supplemented or community-enhanced. We need to shift our entire paradigm from being a Microsoft-centric developer experience to one where almost (*) everything we enjoy comes from us. That means features, tools, designers, docs, samples, templates, and even the respect that I mentioned in my last post. These are all things we’re used to getting from Microsoft and lamenting when we don’t get them from Microsoft and complaining to Microsoft about it. That entire inclination has to die and we have to rebuild a community that holds itself primarily accountable for its own capabilities.

This is not going to happen overnight and it’s not going to start just because I say “go”. I’ve seriously thought through the process, and I can’t see it taking less than a year or two to build out an experience with the kind of polish that can sustainably grow our community. But virtually all the technical pieces we need to build… well, anything, are available somewhere. The extensibility points are there; we just have to do the work both functionally (in code) and culturally (in ourselves). If you were looking for “ThatVBGuy” to post on his blog with some tablets in hand explaining how with a few reg key fixes I can make this all go away, sorry, this ain’t that post. We’re talking 3 steps back, 5 steps forward.

Though technically we’re not sliding backward, we’re just not moving forward right now, so I guess it’s just 5 steps forward while the world is moving forward like 2-3 steps maybe but we’re going to accelerate so that by the end of it we’re far ahead of where we are and even ahead of where we would have been if we just floated along with the current. Yes, we’re in a boat now even though when I started this parenthetical I was thinking about a land-vehicle like a car or a train.

I also want to be clear that not everybody is going to make it to the other side (we’re back on land now, the metaphor is some kind of chasm, I think). It’s completely foreseeable that a lot of us are going to take a faster, easier path and move to a developer experience that’s already propped up elsewhere. There are always going to be those who need a Microsoft-sanctioned/supported solution and either can’t or won’t give up the Microsoft-centric mindset. And that’s okay! I just can’t be one of those people and I’ll explain more about my personal investment in this (other than quitting my job to focus on kickstarting this effort for the next few months) in my next post.

Now, I know I’m not the first to say this is what needs to happen. Everything I’ve said so far will need to be said again, and expanded upon, and most importantly discussed and debated amongst ourselves—we few. So I have to imagine when people say, “Well, what’s the alternate community-driven path?” they already get that the path is to be community-driven. What they really are asking is “How?”, or “Where do we start?”, or “What can I do?”. Maybe they want a roadmap to give them assurances or confidence that this can really be done or how likely it is to be done in a way and timeframe that is applicable to their projects and needs.

For starters, what can you do as a VB.NET developer who wants to help?

Get comfortable with discomfort. We can build some great experiences but first we’re going to build some pretty raw ones. If the minority of the larger VB community that cares to push it forward can’t suspend our discomfort with doing things in a way that may seem initially hacky, we’re not going to get to the place where the majority can follow. Remember that most other languages outside the Microsoft ecosystem are built up like this. VB has enjoyed a long period of being the exception. Now we must rise to meet the rule.

Understand the systems that exist today. You’ve used Visual Studio and .NET but do you understand the extensibility points? Have you ever built a VS editor extension? How well do you understand the dotnet command driver? How’s your NuGet package authoring skill? Do you truly understand how new UI platforms work under the hood? Have you ever written a .NET Analyzer? A source generator? This is the time to pick an area of interest and study up. We’re all going to have our areas of strength and no one person can know or do it all.

Be ready to engage. It’s easy to be attracted to the allure of being the one who comes up with or builds exciting stuff. But what gets projects done and done right is feedback. I’m going to post a lot on my blog as things progress. Be ready to share your opinions and discuss with others. Be ready to test things that are built by others. Roslyn is arguably the largest VB project ever built and it crossed the finish line not just because of smart devs churning through features but equally smart testers constantly testing the bits. Giving feedback on the design. Filing bugs. Fixing bugs. Building projects with what was ready. I hesitate to quantify it but an amazing tester filing bugs is worth maybe 5+ good devs checking in features.

What’s Anthony doing?

First up, I’m building a mod as a proof of concept. This is a different animal than the prototypes and stuff I’ve built so far (think more Resharper than io.js). I’m targeting this month (June) so I plan to have something more concrete to talk about in the next two weeks. Aside from the at-times agonizing process of authoring these posts, this is now my full-time (unpaid) job. And as I learn more, I hope to educate others about how to do the same and begin to coalesce our identity and efforts into everything I can see in my mind’s eye that the VB experience is capable of being.

Need more info?

Sound off in the comments below!


Two Anxieties and One Unarticulated Need

Why doing nothing is sometimes the right thing to do

In several of my recent conversations with folks in and out of the community, I’ve shared some things that they found—and a lot of my readers will probably also find—surprising.

A few years back I penned (as I do) a voluminous response, regarding VB, culminating in an open letter. What may surprise you is that after writing it I really didn’t attempt to socialize it much. I shared it on Twitter but in my experience that’s not actually a VB community hotspot at all. I had initially planned to make a bigger fuss but as I considered next steps and took counsel with those I trust I came to realize that the cycle of inaction-fire-response was just as likely to produce a terrible outcome as a good one (if not more so). Also, I was sleeping a little easier.

You see, in my first 2 years post Microsoft I wrestled with (among other things) two different anxieties regarding VB. I feared that:

1. The C#/.NET org wouldn’t do anything.
2. They would do something and it would be horribly wrong.

And every few months I’d peek in on vblang and find neither an announcement that they weren’t doing anything nor any announcements that they were doing anything in particular. And strangely I’d feel relief for both.

As a side note: if either had happened in 2018 or 2019 I genuinely wouldn’t have been mentally healthy enough to handle it so “do nothing, say nothing” in this case worked out well for me at least.

The Anxieties

In my 8 years at Microsoft attending VB language design meetings and product planning meetings I was constantly pushing back against the idea that the ideal for VB.NET was to “just do what C# does”. “That’s what the customers said they want! They’ll yell at us if we don’t!” Countless discussions that “co-evolution” never meant copying. It was exhausting but a fight worth fighting and after several years eventually I’d built the credibility to really shake that idea out of the heads of those within my sphere of influence.

That idea is wrapped in arrogance and bias and short-sightedness and genuine ignorance and intellectual laziness and yes, good intentions. But good intentions don’t always yield good results.

I’ll restate this plainly because people don’t seem to believe this about me (and I say this with no malice or insult intended): I experience no jealousy toward anything C# has. C# is a phenomenal language with great tooling, but C# has never produced an end-to-end experience in language or tooling that I have wanted to make my permanent home. The “spirit of the language” is different than mine and it can’t be gently nudged into being a great or even begrudging substitute. C# can add functional features, I don’t think the F# community will ever be like, “Yeah, good enough! I’ll switch” and I don’t think adding more imperative/mutable features to F# would allow one to wholesale lift-and-shift the C# community over to F#.

That’s not to say that I dislike capabilities that come to C#. There are many things I’ve wanted before C# even thought of them, and things they’ve gotten that I’ve only been grateful to have missed, and other things I’ve wanted in a very different way than they’ve appeared in C#. But there is nothing that I want because it’s in C#. But the problem is that “everybody” thinks that’s what I would or should want and frame decisions in that way.

Examples time!

So in 2015 we were working on the first release of VB powered by Roslyn. At one point in the cycle we’re prioritizing our backlog for the compilers/languages and I note that we’re doing question-dot (?.) aka “null-conditional member access” next. My dev lead had somewhat recently (re)joined the team and hadn’t been exposed to my philosophy over the years.

He nods his head agreeingly and says, “…Right! Because of co-evolution”.

Me: “No.

Not because of co-evolution.

Because in a private discussion thread with VB MVPs they expressed to us emphatically that `?.` was a top value-add for them. It has nothing to do with C#. The fact that C# also decided to do it is purely coincidental but has absolutely zero bearing on the fact that VB is doing it. We were always going to do it and if C# decided not to do it tomorrow we’d still be doing it“.

Interestingly, there was a heated internal debate on the question-dot (?.) operator while designing it. I can’t recall if this ever went public but the team was split on whether it should be left-associative or right-associative. That is to say whether a?.b.c should mean the same thing as (a?.b).c (left) or a?(.b.c) (right). The former is more compositionally pure and that was the argument that initially led the C# LDM to push forward with left-associativity. But there’s a pitfall there because if a is null, .c will throw an exception. Instead, in order to avoid the exception you’re forced to type a?.b?.c, which is what led the VB LDM to immediately push for right-associativity. Ultimately C# swung around to the right way but it was only after escalating the debate to an executive override. I honestly didn’t expect it and was fully prepared to die on the hill that VB go its own way here despite how “easy” and “comfortable” and “safe” it is to “just do what C# does”. Fortunately that fight never came but I still maintain that it was a fight worth fighting and that it could have very easily gone the other way.

Again you might be surprised to learn that I spent half my time on that release and the one following it convincing folks that we didn’t need to do features in VB. Specifically, that we didn’t need to deprioritize capabilities that would be genuine value-adds to the VB community and the VB experience for the sake of implementing or even pursuing the many ideas that were coming out of the C# design process. The vast majority of those ideas never even made it into C# because of various problems but the impact on the VB side was that they took time and oxygen away from features and approaches that would have benefited VB greatly. But C# was considering them so we had to spend cycles deliberating how they might work in VB.

When we first reached language completeness on the Roslyn compilers and were officially ready to implement new features rather than just attaining feature parity with the native compilers written in C++, I recall a moment when my dev lead (a different one) came to me inquiring about the necessity of the VB LDM: “Maybe we’re at a place where we ought to just ya know, let the C# LDM handle it?”. You see, he truly read both the need of the VB community (and the meaning of the co-evolution strategy) to be that the C# LDM would just do its thing and then skin those features into VB. I explained that this was not the case, but it takes a lot of time and credibility (which fortunately I had) to correct that misunderstanding one person at a time across a giant organization and then across an entire community. I see now that my inability to scale myself was one of my many failings.

The last interaction that comes to mind was from a high level director within developer tools. You see, we had this private mailing list where all of our VB MVPs and trusted influencers could talk shop and give feedback to the team. And anytime anything was amiss anywhere in the .NET ecosystem with regard to VB that list would flame up with someone dramatically proclaiming that this tool or that template was the last straw and that all hope was lost unless nascent technology Y got 500 samples immediately (care to guess how many of those tools, templates, or technologies are now “dead” btw?). Anyway, I sent out a reply asking for patience and calm, as I often did (another failure of mine) and this director privately replied that it was a good response but that he didn’t really see a way out of it as the only way the VB community could ever be happy was if we did everything for VB that we did for C# (in the same way and) at the same time. I absolutely do not believe that could make the VB community happy. I don’t believe doing that ever could have made us happy.

That mindset is like a virus running rampant through both the halls of Microsoft and the broader .NET community and for 10 years of my life I was steeped in anxiety about it all the time. More at some times than others and especially for the first two years where I wasn’t there to fight against it. And then one day “The .NET Team” announced that they had no plans to “evolve” the language further and that anxiety quickly went away. No more fear that some unconcerned and maybe well-intentioned person’s “whoopsie!” mistake would permanently mar the language with an inconsistency or some other mistake. No more fear that the loudest voices in the VB community which really do (for lack of leadership or imagination) yell as often as not for complete replication of C# in almost all respects would find purchase amongst some newer and unwary members of the team and we’d finally get that Semicolon keyword.

And my other anxiety, that nothing would happen. Well, that happened, so there was nothing to fear there anymore either. And in the first few months following the announcement while certainly anxious about COVID-19; racism, police violence, and civil unrest; murder hornets, and economic collapse, for the first time in a very long time VB was something I wasn’t anxious about.

The Need

In the past when Microsoft CEO Satya Nadella has spoken of using empathy to meet the unarticulated needs of users he’s reiterated that this isn’t the same as going off and doing exactly what the most and loudest users tell you; that’s why it’s (often) unarticulated. I haven’t found an exact quote but the closest was here where he says, “It’s not about going where people tell you to, but how you get there before there is conventional wisdom”.

So, if “feature parity” with C# is the red herring—the articulated want that doesn’t actually meet the need—then what is the thing that VB users need. What is all the clamoring and complaining and commenting and protesting really about (beyond the obvious cases of being technically blocked in some task)? The answer is surprisingly human:


The VB audience articulates a lot but behind it all is a very human and professional need to feel respected. Everything else is just a means to that end. Respect from their peers in other language communities. Respect from Microsoft for their decades long business relationship. Respect for their code, and their projects, their knowledge, and skills.

I have a t-shirt (that I never wear) that was given to me one year at MVP Summit that reads “VB.NET IsNot VB6”. What that shirt really says is “Respect me (unlike you treat people who use VB6)”. Every time any VB.NET developer has uttered a phrase distancing themselves from VB6 or VB6-isms it’s because they perceive that doing so gets them more respect. In the mid 2000s, when I was getting into .NET, I did the same thing. “Oh no, you don’t understand, it’s not like VB6 anymore—it’s okay, you can respect me now—I use inheritance!”. I’ve never worn that shirt, that I can recall, and have no plans to because I no longer believe that it’s okay to disrespect someone else as a means to building up your own cachet. But for many VB.NET developers this is still an instinctive and desperate move to scratch up what they really want: respect.

And co-evolution. When a VB.NET developer said “We have the co-evolution promise now” it wasn’t because they were getting the features they actually needed, or wanted, or used. It was a defense from a disrespectful industry. The oft-misapplied idea of co-evolution was a shield that said “You have no concrete examples to disrespect me because I will have the same things as something you do respect”. But make no mistake, copying C# doesn’t create respect. It just deflects superficial disrespect. If you have two children, is it respecting one to treat them exactly like the other always? “I took your sibling to baseball games so I always took you to baseball games ergo I respect you; I bought them blue shoes so I bought you blue shoes—ergo I respect you both equally”.

I recall once 5+ years ago we put out a preview of some potential new features in VB. One of which was the ability to perform a Select Case on the type of a value. Someone wrote in through the “Contact Us” form on the VB team blog and said (paraphrased) “I’m very worried about the direction of VB.NET. I see that you’re thinking of adding this Select Case on type feature but object-orient developers should use polymorphism and method overriding to get different behaviors based on the type of an object and I’m afraid this feature teaches bad habits and is dumbing down the language”. I can’t remember if I replied or what I said but I do recall asking Mads to chime in for some reason and he politely explained that while polymorphism was certainly one way to approach such problems, in functional programming languages it’s very common to use constructs like a type case or pattern matching to do the same things and that we were looking at expanding the languages with other constructs and techniques popularized in functional programming, etc. I’ll never forget the complete 180 in the customer’s response (paraphrased) “Oh! Functional programming! I’ve heard of that! Sounds neat!”. You see, once he understood that the feature was coming from a position of respect for his intelligence and not a crutch, he was completely open to it. Tying it to modern programming techniques like functional programming rather than pre-OOP procedural habits lent legitimacy and respectability to the feature and him and his code in using it by extension.

I can’t tell you how many times someone in the VB.NET community has come to me and said they read that Microsoft was going to evolve VB in a way that was true to the spirit of the language and that this meant “dumbing it down” and that we needed to change to present it as raising the bar of entry or removing the training wheels or some other condescending metaphor. This defensiveness is about respect. Co-evolution was about respect. The distancing from VB6 is about respect and the envy of C# is about respect but none of these things actually meets the need of respect. It’s an unmet and unarticulated need that can’t be solved easily or quickly or superficially.

This isn’t a need that can be met by everyone just “resolving” that they “respect” VB.NET developers. But it can be met, I believe. It’s going to take a lot of work and as much or more of it is cultural (about the community) as it is functional (about features and support). So, you see, I didn’t make as big of a fuss as I thought I would because the last thing we needed then and now is for “The .NET Team” to be startled by some fire drill or protest into doing “whatever” puts out the fire most quickly. Any little addition or change from “The .NET Team” no matter how innocuous or well-intended is as likely to cause as much harm as good to the VB experience unless rooted in the deepest reverence for what VB has already and is, has been, and still can be. I don’t think this is a change that can come from Microsoft and that it’s best that we, the community, take the lead for now. i.e. it’s for the best that outsiders sit on their hands for a bit longer. In my next post I’ll begin to talk about an alternate (and exciting) community-driven path forward that I see. Stay tuned.



How Do I Love VB, Let Me Count the Ways…

You know, I’ve been waiting to use this title on Valentine’s Day for two years. I realized after I posted my exhausting list of differences post that that would have been the perfect title but by then it was too late so, naturally, I’ve just been waiting for February 14th to roll around again… and again.

Anyway, it’s even better now because Valentine’s Day this year falls the day after a very special anniversary. Yesterday marked TWENTY YEARS since the release of Visual Studio .NET 2002 and with it the first release of Visual Basic .NET! That’s a long time.

To commemorate the occasion, a good friend shared with me this book he’d acquired way back in the day with a title that perfectly sums it up:

Visual Basic .NET and the .NET Platform

Just WOW. When this chapter… or section, in the history of VB started I was a junior in high school. I hadn’t even truly discovered the .NET flavor of VB yet but a few years later that changed and my career changed forever.

I’ve been giving lots of thought to the next chapter. But first, I want to try finally putting out that Part II of my list of differences in keeping with the “let me count the ways” title. I tried to get it out by today but it’s been slow going. I’m actually on vacation and hoping to get a good deal more writing done than normal so maybe it’ll come this week. Fingers crossed.

Well, that’s it for now. I vaguely recall encountering or remembering  few extra differences since my first post but I didn’t write them down and have since forgotten them. Hopefully I remember at least 6 more that I can add so I can cross 100 ways I love VB.NET.

Happy Birthday .NET and VB .NET (and C# too); Happy Valentine’s Day everyone and thanks for reading!

Warm and fuzzies,

-Anthony D. Green


This post was written in reverent memory of two colleagues who have passed away since I worked with them, Kieran and Howard. Rest in Peace.

Today’s post is written (in part) from PAX West 2021 in Seattle, which jives well with today’s topic: Enthusiasm. Much of the best parts of my life revolve around enthusiasm. Conventions like PAX, Star Wars Celebration, and BlizzCon are—more than just marketing events—celebrations of enthusiasm. My closest friendships are built around a common currency of enthusiasm for topics and activities. We talk often and at length about our favorite games, movies, TV shows, books, and technology. My preferred YouTube content is from creators with enthusiasm for literature, health, teaching, or just knowledge in general. The online communities I participate in are powered not by organizations but the enthusiasm of their community members. I remember my favorite time of year as a Program Manager on the VB team was MVP Summit because of how exhilarating it is to just be around others who are enthusiastic about programming in my favorite language on my favorite platform. I realize that though across a wide range of domains, at my core I’m an enthusiast. In fact, when Microsoft first approached me about interviewing for the role of PM of the VB.NET compiler back in 2009 that’s precisely how I signed my email accepting the invite. Not “Professional IT Solutions Consultant” or “Enterprise Software Architect” but “Visual Basic Enthusiast Extraordinaire”.

In the beginning of this year, I mentioned taking a break from social media to get some quiet, so to speak. I’m happy to say one of the words to tumble out of that quiet was this: enthusiasm. Not fandom. Not fun or favoritism. Not ego. Not even love or passion. I’d been thinking about my reasons for continuing to think about VB and in VB and those other words while certainly undeniable to various degrees didn’t feel super defensible to me as a case for why anyone else should care what I have to say, how I feel, or what I do. Not defensible to these imaginary critics, btw, but defensible to me. But unlike loving what you do, or having a fun job, or being a fan of your tools, I think it’s pretty difficult to argue that a life, professional or otherwise should be carried on devoid of or without regard to enthusiasm. That doesn’t mean that every single day I sit at my desk and laugh hysterically and post on Instagram videos of my saying “Isn’t this so fun!? My desk is the happiest place on earth today!” but there’s still a general enthusiasm (what defines and encourages that enthusiasm is a topic for later) for the field taken on the whole that I believe is absolutely worth fighting for.

While pondering this idea several people come to mind, some as counter examples, but I’ve decided today to focus on the positive. Specifically, two immensely respected past colleagues with inspirational careers who have since passed on and I’d like to talk a bit about how they’ve influenced my thinking on this topic.

The first of which is a man who I didn’t interact with very often personally but who was one of several role models for me at Microsoft. When I joined the Visual Studio (Managed) Languages team I was advised to get a few mentors and I did. My peer mentor’s mentor was a man named Kieran. Kieran said something that I’ve never forgotten and which I think summarizes what I mean when I talk about enthusiasm, “I always want to run those last few steps to my office in the morning”. And whenever I remember Kieran, that’s how I picture him, hustling to his office toward whatever the day’s challenges were. Not that every day was a trip to the amusement park but that, on the whole, he was going somewhere he very much and wholeheartedly wanted to be. That’s the example he set for other PMs and for me and his loss 3 years ago no doubt left the world dimmer for a lot of folks for a lot of reasons.

Another person who’s been on my mind is Howard. I worked with Howard a little over a decade ago in Chicago. When he joined the company I was then at, he was already in his mid-60s. He was the most knowledgeable person I knew about business process orchestration and far from thinking about retirement he was always thinking about what was next. His enthusiasm for his work was inexhaustible. I ran into him a few years into my time at Microsoft and he was still at it as of last year in his mid-70s. I think of Howard as an example of a long and wholehearted career. Sadly, when I went to look Howard up before writing this post, I learned he passed away late last year. I left my condolences with the family through a page they set up and I repeat my sympathies here. This loss to his family is of course beyond my comprehension and words and I will always cherish his time in my life as a respected, amicable, and resilient colleague and as an inspiration.

I could go on listing individuals near and far who “worked” in their fields in their 50s, 60s, 70s, or 80s and beyond, from Sir. C.A.R. Hoare in computing to Dr. Anthony Fauci in immunology, other members of public service, entertainment, and industry. I mention all of this to say… I’m 36 (37 in exactly 1 month). When I think about some of the brilliant and tireless minds I’ve worked with on the Roslyn team and the length of a career there’s a very real possibility that I’m not even halfway through mine. There could be another 40+ years of me giving a damn in the general vicinity of computers and programming in some form or fashion. How do I want to spend them? Rolling out of bed in resignation or running those last few steps?

Something happened to me, y’all. I once referenced fighting to stay on a platform, but I realize I’m in a fight for my very enthusiasm for what could be a longer period of time than I have been on the Earth. Will I be silent? Will I connect with others? How? Do you know how many times someone I know or who knows someone I know has contacted me and said “I want to get started with programming, where do you recommend I start?” and I genuinely just had emptiness in my heart and nothing to say? This has been true for several years now, at least 4. I lost something vitally important because I let externalities convince me that my own enthusiasm didn’t matter. That it was immature, trivial, or irrelevant. At times in the last 5 years, I’ve thought of myself as on a journey looking for the soul of something and this year I’m realizing that my soul is at least part of what I’m looking for.

What’s the impact if I give up on that search or if I bow out of that fight? The impact for me personally? The impact on others, or the lack thereof because I never share what I’ve learned along what has been a rich career (that’s not even half done yet). And this has made me think about what enthuses me about our industry and what definitely does not (and it’s not precisely a particular tool or product, btw). Anyway, in this time of silence I’ve resolved that while I might face a lot of criticism no one can ever tell me that it’s wrong for me to fight for my enthusiasm for the next 40 years of my career and my life. Not just as a clinically depressed person but as a human being I believe that’s however narrow the odds, that’s always worth fighting for!



P.S. My next post has been titled “Two Anxieties and an Unarticulated Need” but I’m on the fence on how soon to post it. I’ve been holding on to it for over a year and I’ve sort of lost track of whether it’s important to say it now. I’m leaning yes but thoughts change. I’m at least leaving you the title, so you know there is a next post. There’s always a next post.