Here is a proposal for a enhancement to Groovy that would allow us to make incompatible changes to Groovy syntax between releases, but not require users to go back and change all their code all at once. I am not proposing this enhancement be made for 1.0, but am putting it forward now to show the feasibility of such a mechanism.
From time to time, it will become evident that it is in the long-term good of Groovy to make a language change that results in new releases of Groovy not being able to run programs written for older releases of Groovy. This is called a backwards incompatibility.
This proposal provides a mechanism that eases the pain of introducing backwards incompatible changes to Groovy.
The compiler recognises a special annotation, "@Future" at the start of the file or compilation unit. It can be thought of as annotating the package declaration, if one is present. The parameters to the annotation tell the compiler which "future features" to use when compiling this file.
Let us suppose for example, sometime during the development of Groovy 1.3, we decide that unicode escapes (
\uxxxx) should not be processed as per GLS/JLS 3.3 inside of
/RStrings/. We need to give people enough time to modify their old source code though, so we say that the new feature will not be the default behaviour until Groovy 1.5.
To use the new feature in Groovy 1.3 and 1.4, users will have to put an
@Future(noRawU) annotation at the top of their source file, like so:
Old source code will still work fine, but will cause the compiler to generate a deprecation warning, unless it is modified to include an
This mechanism is largely borrowed from Python. The Python mechanism is documented in PEP-236. Along with PEP-5 that document also outlines the Pythoneer's take on the process for deprecating language features and what constitutes a reasonable amount of time for migration to take place.
What is the Rationale, Really?
We need to ship Groovy 1.0 soon, ideally within the next eight weeks. However, despite the recent progress on many aspects of the scoping and name resolution issues, we still face a dilemma. On one hand, Guillaume, tug and others make the very reasonable point that it is far too late in the release cycle to be fiddling with markup and closure syntax, especially when the current, mixed syntax can be made to work fine in the vast majority (perhaps all) cases. James, blackdrag and others have argued that the mixed syntax results in subtly but definitely sub-optimal name resolution rules and should be fixed.
Knowing that a reasonable mechanism exists to allow language evolution means that perhaps we can agree to ship 1.0 with the mixed syntax, then revisit splitting closures from markup after the 1.0 release has settled down a little.