As an example of how VB .NET threw its lot in with the MSDN camp instead of the Raymond Chen camp, Joel points to the example of the disappearance of Set and parameterless default properties. (I should add that Joel slightly misspoke again – VB still has default properties; now, though, they can’t be parameterless.) This is an interesting design point to pick because it was one of those that unambiguously showed the dilemma that we faced when moving to .NET. Namely, how do you do two mutually exclusive things at the same time?
You see, when we started out on the grand .NET experiment, lo those many years ago, we were all Raymond Chen-ites, every one of us. We were going to port VB to this new .NET platform and, by golly, it was going to be 100% compatible with the previous version. We had all kinds of assurances from the CLR team that they were going to support whatever we needed to make us compatible. We had all kinds of directives from management that compatibility was paramount. So we set off busily building a product that would allow migrating VB6 code unchanged to this new platform and would make VB .NET be a no-brainer upgrade for our millions of users.
So, what happened? Among other things, reality asserted itself.
Let’s use Joel’s example, because it’s an excellent one. One of the cornerstones of .NET was that it was a multi-language platform. No longer would one language be crippled in favor of another – no! We were all going to be on a level playing field. Only… well… there’s this little problem with assignment operators. Because, you know, VB has these two types of assignment: value (Let) assignment and reference (Set) assignment. And the C-style languages (C++, Java, C#) have only one type of assignment that changes meaning depending on the type of value you’re assigning. OK. No big deal, right? Each language can keep its own way of dealing with assignment, right?
Yeah, but then there’s properties. A key feature of properties is that they allow you to define what happens when you assign to the property. Hmmm. Assign. As in the assignment operator. As in “two types of assignment” vs. “one type of assignment.” But we’re still cool, right? Because the CLR allows you to define multiple “set” accessors for properties. Yes, that’s it, VB properties will allow users to define both a Let and a Set property accessor and the C-style languages will allow users to define only a Set property accesor. And everybody will be happy, right?
Until they try and work together, that is. You see, the flaw in this little argument is: what about the class libraries? Yeah, class libraries. Little things like, oh, WinForms and the Base Class Libraries. Because, you see, those libraries were supposed to be used by both VB and the C-style languages. And there was just no way to finesse the issue that the two language camps had two approaches to assignment when trying to write properties that would work with both languages equally well. Believe me, we banged our head against the wall for a long time trying to invent some scheme that didn’t require one language or the other to contort itself. We thought about ways to make properties with just a Set to map correctly to a Let/Set. We thought about ways that properties with a Let/Set could map correctly to just a Set. In the end, though, we came to the conclusion that there was no good answer. Either we had to foist what looked like completely arbitrary requirements on programmers working in the C-style languages (i.e. surface the “two types of assignment” in C++/C#), or we had to deliver a seriously sub-par experience for developers working in VB (i.e. surface the “one type of assignement” in VB). Or we could take a third way – drop Let/Set assignment, drop parameterless default properties, break existing code that used them, and adopt a unified type of assignment.
To be clear, this is not “the reason” why VB .NET is not 100% compatible with VB6. This is just “a reason” that is representative of the sea-change that existed when moving from the Win32/COM platform to the .NET platform. But it is illustrative…
(As a postscript, I’ll add that parameterless default properties were always a bit weird because it appears there were never any clear rules about how they worked. If I remember correctly, not even the developer who owned the compiler’s semantic analyzer at the time could explain what was supposed to happen in some fairly straightforward cases. The spec was the code – as long as test cases from previous versions worked, the code was “right.” Ug.)