At long last, I am done with Chapter 9. The actual writing process didn't took so long, but the ideas took a long time to come into a coherent form.
Here is the final table of content:
9.1 Starting from a stable origin
9.2 Planning our DSL's versioning story
9.2.1 Implications of modifying the DSL engine
9.2.2 Implications of modifying the DSL API and Model
9.2.3 Implications of modifying the DSL Syntax
9.2.4 Implications of modifying the DSL Environment
9.3 Regression Test Suite
9.4 Versioning Strategies
9.4.1 Abandon Ship Strategy
9.4.2 Single Shot Strategy
9.4.3 Additive Change Strategy
9.4.4 Tower of Babel Strategy
9.4.5 Adapter / Compatibility Mode Strategy
9.4.6 The Great Migration Strategy
9.5 Applying versioning strategies
9.5.1 - Managing safe, additive, changes
9.5.2 Handling required breaking change
9.6 DSL versioning in the real world
9.6.1 Versioning Brail - Boo based templating language
9.6.2 Versioning Binsor - Inversion of Control Container Configuration DSL
9.6.3 Versioning Rhino ETL - Extract Transform Load DSL
9.7 Versioning - only at release boundary
And the chapter summary:
In this chapter, we have discussed how we can ensure the longevity of our languages, how we can make them survive and prosper from one version to the next.
Of particular importance are the tests and the regression test suite, which we use to ensure that existing behavior is not changed in an incompatible way, those breaking client scripts.
We also discussed the implication of versioning on the design and implementation of our DSLs. In particular, we mentioned the importance of using façades to separate our DSL from the application's model and API, in order to allow them both to be developed independently. This separation goes a bit further than merely a façade, however. We want to ensure that the DSL engine is usable even without the DSL.
This seems like a strange requirement, but it is a very important one. You want to be able to modify the engine without modifying the DSL, and vice versa. In addition to that, you might want to have several dialects of the same language (typically several versions) based on the same engine. This tends to be hard to impossible if there isn't a good level of isolation between the two.
The DSL environment (evaluation order, invocation call sites and naming conventions)and its implication on versioning are something that most people tend to forget about, until they find out just how critical it is for the usage of the language.
We walked through several versioning strategies, from the "we always start fresh" to the "no changes are allowed" to multi dialect languages and automatic migration tools. We also applied a few of those strategies to the Quote Generation DSL, and then seen how real world DSLs have dealt with the problem, and the various constraints that led to the different choices that were made.
Versioning is a big topic, and there is not enough room in a single chapter to cover it all. Most of the guidance about versioning is directly applicable for languages as well, and I strongly recommend referring to it as well as this chapter.
At this point, we are surely ready to release our DSL to the whole wide world, right? Well, from the technical perspective, certainly. But we are still missing something, a bit of shine, just a hint of polish.
Creating a DSL is easy, making is slick and professional is another matter, that is what we will spend the next chapter discussing.
Next chapter - Creating professional DSL.