Language Stability
 




A Whitepaper by Dan Barclay
Microsoft Visual Basic MVP, 1993-2001,
Copyright ©2001 Barclay Software, Inc., Orange, TX

This document describes Language Stability, as discussed ad infinitum in various newsgroups since the initial public beta release of Visual Basic.Net. In most of these discussions the term is not well understood, nor are the effects well enumerated. “I know it when I see it” descriptions and “I need it” effects have little meaning to anyone.

The purpose here is to describe what the term Language Stability means to the author and to others having valuable code assets. While open discussion of the subject is new, the concept is as old (and as important) as programming itself.

The principal of Language Stability exists in the marketplace. Fallout from changes in computer languages is not new, nor is it restricted to any one language or timeframe. The point here is to observe and describe it as clearly and as explicitly as possible, not to determine what it “should be.”

This paper will be modified for clarity as needed. Others should send their comments and observations on this issue to Dan@MVPs.org

What does it mean?

Language Stability is that feature which allows source code to continue to function as originally designed (and tested) over transitions in compiler/interpreter versions.

Secondarily, Language Stability allows continued use of existing, trained developers, thus facilitating higher skill levels as experience grows.

Language refers to the core language of a development system as opposed to the product itself. That is, the core syntax and behavior of written code. Excluded from this term is functionality that changes in character with operating system or platform context (many API functions and user interface functions). That is not to say that Product Stability is not important, only that the discussion here regards Language Stability.

Stability allows extension of language features and functionality while preserving existing behavior. This is not to be confused with stagnation, which prevents any change including improvement.

The end result of a stable language is that a Module from one release will compile and run correctly in the next release provided only that the Module is restricted to core functionality (no platform specific API’s or UI but otherwise any code in any Procedure). On rare occasions it may be necessary to make trivial modifications to source code in the earlier release to have the code work in the later release. In any case, the end result would be code that works correctly in either release without modification. A byproduct of this is that a developer can now move code from several releases prior to a current release with minor or no modification.

Why does it matter?

First let’s define a few parties, because how and why it matters depends on your point of view. 

  • Application Owner is the entity with the ownership stake in an application whether the owner is a person or a business. 
  • Library Owner is, for all practical purposes here, synonymous with “Application Owner.” 
  • Developer is the individual (programmer) using the language product. A Developer either works for an Application Owner or is the application owner himself. 
  • Vendor is the vendor of the language product.

Completed Code is an asset to the Application or Library Owner. The source language is the container for that asset. The values associated with an asset container (a Bank as a container for money, for example) are the same values used by the Application Owner to assess the suitability of a source language. Other features of a language (ease of use, or features of the product that contains it) are important, just as friendly service and good location are important to a Bank. However, in both cases the fundamental purpose is to hold a valuable asset. Friendly staff makes little difference to you if your money is not safe. First you decide which banks can safely hold your money, then you decide which of those is most convenient and offers best service.

Language Stability matters if you create code libraries intended for reuse. Code libraries include both internal (personal, corporate, application) and external (purchased libraries, publicly available code). While this may not be such an issue for lightweight (short term scripting and utility) applications, it is critical both for Rapid Application Development (RAD) and for development of New Legacy applications.

RAD, in particular, requires reusable code libraries. There is no more rapid development methodology than one in which much of the application code is already written and tested. As a result, Language Stability is simply a prime requirement for RAD. Library functions originating both from outside (web sample sites, purchased libraries, etc) and in-house libraries are routinely used over many versions of a development product. Library functions are also used in common for many, if not all, applications created by a given group of application developers. To be of value, the functions and methodology provided in these ways must be valid over a long time frame. In addition to the rapid development scenario, many times RAD is used to create mission critical applications.

Development of mission critical business applications (a.k.a. New Legacy applications) absolutely requires Language Stability whether the development is RAD or otherwise. These applications are intended from the outset to provide functionality that is core to the businesses they serve… functionality that will be required as long as the business itself lives.

While New Legacy applications will be extended with new functionality over time, the core functionality must be provided or the business cannot function. Design of New Legacy applications dictates that the business functionality be designed to survive transitions of operating systems and platforms. Code that can be isolated from the outside world, in theory, need never be changed once it is written and tested. Functionality requiring access to the “outside world” (including user interfaces, OS interfaces, etc.) is provided with wrapper functions containing interface code such that even significant platform changes are managed by replacing only the interface wrappers. This core library is a significant, perhaps critical, business asset for the application owner. Some businesses, in fact, assess their applications and source code as formal entries on their Balance Sheets such that failures of Language Stability has a direct effect on the value of the company.

From the above description, one would think Language Stability would matter only to those developers and owners creating an application for the ages. In reality nearly all developers, and certainly all application owners, believe the application will live for a very long time or they wouldn’t be making the investment. From the developer’s standpoint, that function written late into the night, tested in the early morning hours, and placed into the library has no business being approached again except by calling the function from the outside. From the application owner’s standpoint, the library created and paid for with time and dollars is intended to be a permanent asset to be used as a foundation for the future. Even the fact that most applications and most code never make it into production use is irrelevant; the intent of both developers and application owners is the factor that guides them. Vendors intent on winning the minds and hearts of “new Developers” may be well advised to recall that “new Developers” train with and under the guidance of existing Developers, while working for Application Owners. While they may take input from various sources, Application Owners (not Developers) make the ultimate decision on which language and developer products to use.

Again, the language is the container for code assets and those assets are considered to have high value. Faith in the safety of that container, and Trust in the vendor supplying it, are paramount.

Factors affecting a Standard for Language Stability

Ideally a language would never be changed in a way that caused existing code to misbehave. That is, and should be, the goal from an Application Owner’s viewpoint.

Failing that, it is critical that when changes must occur, they occur in a manner that causes almost no disruption to the application product lifecycle. If an application is expected to have a long life (from above, nearly any application), the language being considered must have a demonstrated history of improvement without disruption of application products. Keeping in mind the viewpoint of the Application Owner, any disruption causes concern and loss of Trust as a source container. Multiple instances of disruption indicating a pattern are of particular cause for concern. That is, the Application Owner considers Language Stability to be an attitude of the language vendor. Promises and Standards mean little in the face of history.

The author has transitioned and extended library code over multiple operating system and product bases using Microsoft Basic. These transitions ranged from CP/M and TRSDOS versions to 32bit Windows versions of a family of applications. In the experience of the author, the Standard below will reduce disruption to a level that can generally be tolerated by an application product. This Standard is based on observations that:

  1. Applications generally are not released using the newest language product version, even when the application developer converts and implements exploratory testing on new language product versions. Application ‘release versions’ generally retain a given language base version until there is some compelling feature, or platform change, that makes a new release base worthwhile. As a result, when a new language product version is used as a base, the “previous” version is likely to be several releases prior.

  2. Long lived applications require some period (generally over a year) in which an application based on “a previous release” is supported and enhanced in parallel with that same application based on “a current release” of the language product. This is particularly true when spanning platform changes. During this period it is crucial that maintenance of a single code base be possible so that application product enhancements transition seamlessly to the newer version.

  3. When large libraries are involved, which is generally the case for mission critical or vertical applications, even seemingly minor language changes become overwhelming.

  4. Changes to “legacy” functions often are extremely difficult as a result of programmer turnover or lack of current application domain expertise. The answer to the question “Who knows how this is supposed to work?”, generally goes unanswered even by the developer who researched the application feature previously.

  5. Rewrite of applications or libraries generally takes significant calendar time (12 to 18 months would not be unusual). Development on the primary application features comes to a halt during this time, which is unacceptable for successful applications.

  6. Changes in a language cause the need for a conversion. Once the need for a conversion is determined, in a generic sense, the Application Owner considers all language alternatives. When conversion to an alternate language appears to be comparable in difficulty to conversion to a new version of his current language, it appears to the Application Owner that there simply was no defined language there at all.

Standard for Language Stability

The following general Standard for Language Stability falls from these and other experience:

  1. Features, language, and syntax are retained unless there are compelling reasons to remove them (example: features related to hardware or platform specific features that simply do not exist in a new environment, a la PEEK/POKE).
  2. Elimination of language features is only allowed if:
    1. It is clear the feature is no longer in use, and
    2. A suitable way of implementing the functionality (exactly) has been provided for three (3) full releases or a platform change, whichever is greater, and
    3. The depreciation of the feature (stating explicitly that it will disappear, not just stating “we don’t like this”) is clearly documented in prior releases, and
    4. Code editing is trivial (or automated) to implement the alternate functionality, and
    5. The change makes sense to nearly all users, and
    6. The change causes execution or compile failure (as opposed to incorrect results) if legacy code is used, and
    7. Keywords are not reused or otherwise have their behavior changed, and
    8. This seldom happens over the life of a language.
  3. Default behavior is not changed.

The Standard applied to examples of changes:

Using Microsoft Basic as a context the following examples show changes in the language, some breaking Language Stability and some preserving it.

Changes that would not break Language Stability:

  1. “GoTo LineNumber” versus “GoTo Label”. “GoTo Label” was provided as an alternative as early as QuickBasic 1 or 2. VB.net now requires a colon behind a line number. The editing required to implement this change is trivial and does not require changes to the logic of a code fragment. Target line numbers are easily converted to labels in earlier versions of MS Basic (including DOS versions) allowing the same syntax to work in more than one version. Given an announcement of this impending change several versions ago this change would cause little concern.

  2. On xxx GoSub versus Case (provided GoSub still worked). This would have been a viable change, provided GoSub still worked. “Select Case” provides an exact substitute for the switching available in “On xxx GoSub” and has been available for many years including DOS versions. Again, given an announcement of this impending change several versions ago (and if GoSub still worked) this change would have caused little concern.

  3. Replacement of DEF FN (years ago) with Function. This change was made years ago, after a procedure based Function was provided. The single line function definitions were easily wrapped in a formal Function procedure.

Changes that break Language Stability:

  1. Change Type to Struct. There is no reason, compelling or otherwise, for this to change based on the OS or platform; the feature is in use by most developers, and no alternative has been provided in parallel.

  2. Eliminating GoSub. There is no reason, compelling or otherwise, for this to change based on the OS or platform; there is no direct replacement; the feature is still in use as a “code only” container similar to nested procedures in Delphi.

  3. Changing established data types (Integer, Long, ($tring)). There is no reason, compelling or otherwise, for these to change based on the OS or platform; the feature is still in use by nearly all programmers; a direct replacement (ex: Int16) is not available in earlier releases; these change types of data for an existing data type (a new type of data needs a new data type).

  4. Changing ByRef to ByVal as default parameter behavior. Changes default behavior established when procedures were introduced in early DOS versions of the language.

  5. etc., etc., etc.

So now what?

So, now that the language has changed significantly what comes next? That is difficult to say. Many application owners are seriously studying their path forward, and there are several issues in the choice.

The issue of “platform” is an important one to be sure. At this point the only compelling platform is Windows. While dotnet can create Windows hosted applications, existing development tools seem superior for that purpose at this time. Dotnet and Linux are interesting as a new architecture or platform, but not yet compelling enough to force a transition.

From the author’s own point of view, it would have been interesting to create some cousins of existing applications using a distributed architecture based on dotnet. However, those applications are not core and the effort required to convert (then maintain) the common library code base is completely unreasonable.

The issue of Language Stability is certainly critical. Conversion to another language from “Classic VB” is clearly possible. Automated tools either of in-house or purchased origin will help significantly so the primary issue here is to determine a suitable endpoint based on the platform(s) anticipated for the target application market. Some of the options are considered briefly below:

MS Basic
Not an option (barring a full correction of the language). Given a fully compatible language (allowing continued support of Windows applications in parallel) this would be the clear choice for the longer term future. However, based on previous language instability it is unreasonable to expect even the current “vb.net baseline” to remain constant for the future regardless of promises to that effect.

Pascal (Delphi)
Seems to be stable, good tools support, support on Linux as well as Windows. From early conversion efforts it seems reasonable to create parallel versions (VB/Delphi) using automated tools. At this time conversion of VB applications to Delphi seems to be far easier than conversion to vb.net.

C/C++
very stable, good tools support, more difficult application creation and maintenance than Basic or Pascal. Automated conversion of Basic code is difficult. If Language Stability were the only issue, this would be the clear choice.

C#
Questionable stability, new language brought to us by the same development team as MS Basic. Potentially more stable than VB.net simply because C# code is used extensively within the .net library. Only supported in dotnet.

The author’s own expectation is to keep applications in existing versions of VB for the foreseeable future. Work on conversion to another product (Delphi initially) will proceed as a “background task.” The purpose of the conversion is to assure a path forward on the basis that vendor support for VB will eventually decline. Secondarily, using a common library to create small server functions living on cheap Linux boxes is quite interesting. “Keeping the options open” and a long-term strategy is the key here, as there is no need for immediate wholesale conversion.

Given a change of heart by MS on the definition of Visual Basic this author would be back in the fold so fast it would give one whiplash. With the existing library core, creation of dotnet spin-off’s for market exploration would be trivial. Unfortunately, to be convincing Microsoft would need to return all the existing syntax and behavior (as their original “Guidelines for Language Change” seemed to clearly specify), and clearly state a positive position on Language Stability. That does not seem to be in the cards at this point. They seem to want to make believe that they will retain stability “this time”… but I’ve heard that before.

What will other Application Owners do? Frankly, I don’t know for sure. At the same time, I’ve had a lot of input from others in similar circumstance that indicates a position almost identical to my own. To be sure, some programmers are wowed by dotnet (including VB.net). “Cool new features” go a long way with early adopters. At the same time Application Owners are stunned as they begin to understand what is happening here and it is difficult to tell what the full reaction will be. There are, quite literally, billions of lines of working MS Basic code that will require rewrite simply to move to the next version of the “same” language.

It’s a shame, too. MS Basic was an excellent choice for application development for such a long time. The really sad part is that all of the “Cool New Features” could have been implemented without losing Language Stability.

Language Stability is a Feature. I wish Visual Basic had it. It still could, and I know how to make it happen. If only they cared…

Microsoft Basic… R.I.P.

-- Dan, November 26, 2001