Way back in the mists of time (better known as January), I wrote two entries on the default instance feature we’re reintroducing in 2005. The first talked about what default instances are and the second talked about why we thought they were a good idea. I promised at the time to talk about the criticisms that have been leveled against the feature “soon,” but that “soon” has turned into “two and a half months or so.” This is partially because my work load suddenly ramped up, but it’s more because my blog entries and the accompanying comments prompted another round of internal discussion over the feature. That, unfortunately, took much longer than I wanted it to, which further delayed this (since I didn’t want to say one thing only to have to take it back later). So I apologize for the delay in getting back to this.
Anyway, now that we’re past that, the objections to default instances seem to tend to boil down to two major issues:
First, although default instances exhibit most of the attributes of singleton objects, they are really only “semi-singletons” because they can still be instantiated. In other words, in addition to saying Form1.Show(), you can also say “x = New Form1()” and then “x.Show()”. When you use New, you’re creating a second (or third or fourth…) instance of Form1 that is totally separate from the default instance. The relationship between the singleton form and the instantiated form can be obscure at best, causing confusion between the singleton nature of the default instance and the multi-instance behavior of the normal type.
Second, a default instance that can be accessed through the type name (at present, only form default instances do this) erases the distinction between instance and shared members. When I say “Form1.x,” I have no way of knowing, without looking at the object browser or MSDN help, whether “x” is a shared member or an instance member.
(There is a third objection that because non-dialog Windows Forms lose state when they close, default instances are not as useful as they were in VB6. This is a limitation of the Windows Forms design, not VB – when a form closes, everything on the form is disposed, including the controls. Bill proposed a workaround that, I’ll confess, I don’t entirely understand, but it’s something we’re talking to the Windows Forms teams about, although I wouldn’t expect anything for VB 2005.)
The bottom line is that both of the major criticisms of default instances are valid. Despite their usefulness, they do create some semantic confusion that did not exist in the language prior to their re-introduction. Why, then, did we do it? In the end, we felt that, on the balance, the semantic confusion created by the feature was greatly outweighed by its usefulness. Working with forms (and, in VB 2005, web services) as default instances is a very natural and understandable way of doing things, regardless of experience level or knowledge of the language. In our continuing quest to make Visual Basic the most approachable and easy to work with language, this seemed like a very natural feature, not just because it happens to be compatible with VB6.
The standard rejoinder to this line of argument is, “well, fine, re-introduce the feature if you must, but why must you make me have to deal with it?” In other words, “why aren’t default instances optional?” This has been the subject of many long-running discussions internally and we’re open to the idea, but found no good way to do so in this release. We considered introducing a single instance/multi-instance mode switch into Windows Forms, but that would mean that changing the instancing mode of a form would cause drastic changes in the way the form was used in code. Thus, it would be vital to choose up-front whether a form was going to be single instance or multi-instance, and woe be unto the developer who chose incorrectly. We just didn’t feel that was a good user model for the feature.
The other major idea we considered was introducing some kind of configurable warning into the product that would allow people to turn the use of a default instance into a warning or error. This seemed much more palatable, but ultimately died because of what it would imply: warnings and errors indicate code that is probably or definitely wrong. They’re intended to ferret out errors, so adding a “warn on use of default instance” warning would imply, well, that using a default instance is an error, which is something that we don’t believe.
So, where does that leave us? One idea that we’ve started to kick around is the idea of integrating the concept of a “programming style” into the product. In other words, if your programming style is to not use default instances, great – you set that style parameter and then the compiler will warn you when you violate that style. Once you start down this path, you can imagine a great number of possible style settings that the compiler could flag – things that are entirely legal and valid, but which someone somewhere might not like. Unfortunately, this kind of feature is well beyond our VB 2005 schedule. However, as we start to think beyond our existing release, we’d love to hear what you think about the idea!
(For the less-aged among my readers, the title of this piece refers in an ironic way to the seminal paper Go To Statement Considered Harmful by Edsger W. Dijkstra, one of the founding luminaries of the computer science field. I would also note in passing that Visual Basic still has a GoTo statement…)