Whenever someone modifies a computer program they should always ask themselves ``what is the impact of these changes going to be on users''. For mature products, the degree of impact is largely determined by the investment that users have made in particular file formats supported by the product.
At the two extremes, there are the video game and the compiler. If one changes a video game, the change affects only the future games played. However, if one changes a compiler in particular ways, it is likely that thousands of users will be forced to change millions of source files to accommodate the new version. Thus the impact of changes to a program depends largely on the investment made by users, in source files, training, and even muscle memory!
FunnelWeb lies very much at the compiler end of this spectrum. In fact it lies even further. Not only does it implement a language, but it is currently the only implementation of that language! This means that, although they shouldn't, people will be tempted to treat the FunnelWeb program as the definition of its input language instead of the definition chapter in the FunnelWeb User's Manual, which takes precedence.
Because FunnelWeb defines an input language, and people will write programs using that language, particular kinds of changes in the language will impact severely on users. Three different kinds of change are discussed below.
1cm 1cm Removing features: Removal of features (featurectomy) is extremely difficult once the user base has started using them. If a feature is removed, users of the program will have to go through all their programs and find a way to simulate the effect of the removed feature with other features. Often this is so unthinkable, that bad language constructs are tolerated far beyond their useful lifetime.
1cm 1cm Modifying features: Modification of features has less direct impact than the removal of features, but can cause more subtle errors. For example, consider the sorts of subtle errors that might arise if the semantics of the FunnelWeb comment @! were changed so that it no longer includes the end of line marker. Anyone modifying features should be sure that they are not inadvertently laying traps.
1cm 1cm Adding features: Although the addition of features is generally the most painless for the user community, as Hoare points out, it is also the most dangerous in the long run.
``When any new language design project is nearing completion, there is always a mad rush to get new features added before standardization. The rush is mad indeed, because it leads into a trap from which there is no escape. A feature which is omitted can always be added later, when its design and its implications are well understood. A feature which is included before it is fully understood can never be removed later.''[Hoare80]
[1]
These problems exist even when there is a central authority. If we consider the case where there is no central authority, and users modify a language and its implementations and distribute the modified versions, the result is even worse. For a start, the structure of the genealogy of the program changes from a list to a tree. This makes it impossible to impose an ordering on the different versions and makes it difficult to merge them once they diverge. Second, it reduces the portability of files created under different versions. Third, it makes adding features hazardous. If a feature is added in one version, files will be created that use it. These files will immediately become non-portable. Furthermore, two programmers may introduce different features that use the same syntactical constructs, thus preventing the two versions from ever being merged. Worse, two programmers could introduce similar features that use the same syntactical constructs, producing even more subtle problems.
The only way to avoid all these problems is to create some sort of central design authority, (or, at the very least, some sort of design synchronization) that controls the language and its implementation.
The benefits of tight control over the language are enormous.
1cm 1cm Universal portability: Source files can be treated as portable. If all the language implementations in the world are singing the same tune, then someone in Sydney could send a file to someone in New York and be sure that it will be successfully processed.
1cm 1cm Clear semantics: Doubt about the semantics of the language will be greatly minimized. So long as more than one slightly differing version of a language exists, there will be confusion over the semantics of its constructs. A good example is the confusion between the AT&T Unix and Berkeley Unix shell languages.
While changes to the language supported by a piece of software is the most serious problem associated with multiple versions of software, the lesser problem of keeping track of changes that don't affect the language that the software implements can also cause trouble. Merging different versions of software is extremely tedious as anyone who has tried it will verify. However, changes not affecting the language are far less serious because they impact only on the program itself, not on the far more numerous source files that depend on it.