The OOMMF project has done a lot of this. Examples below. DGPSee also Changes in Tcl/Tk for a source of things which can be done.
Here's a start:
- glob forwards compatibility
- file forward compatibility
- grid forward compatibility
- clock forward compatibility
- fcopy forward compatibility
- destroy forward compatibility
- menu forward compatibility
- string forward compatibility
- lindex forward compatibility
- lmap forward compatibility
- lset forward compatibility
- forward-compatible dict
- lreverse
- forward-compatible lassign
- Forward-compatible try and throw
- Forward-compatible tcl::prefix
- Forward-compatible lsort
- Forward-compatible dict map
- ...
Seems to me that these are good candidates for Tcllib!Some like try and throw are already there. In the mean time, I EF am collecting some of these into a module of the TIL. If TIL is properly installed, accessing some of those commands from older versions of Tcl is only a matter of package require compatibility. This will work starting with 8.4 and fully on 8.5. The implementation addresses possible dependencies between the commands, e.g. whenever a forward compatibility implementation requires another command that was not present in that Tcl version. It also makes as little use of {*} for maximising 8.4 compatibility. Presence of the 8.6 feature set under the running Tcl is tested dynamically to benefit from system-wide forward compatibility solutions that would already be in place and benefit the script requiring compatibility (e.g. on older Ubuntu installations, dict is available for Tcl 8.4). At the time of writing, the set of compatible commands implemented as part of the module is: lassign, lmap, lreverse, lset, dict, throw, try, tcl::prefix, lsort, dict map. While packaging and inclusion is by EF, most of the hard work is by AMG!
Note this can be done in Tcl's C code too:
- Tcl_GetStringResult() forward compatibility
- Tcl_GetChannelHandle() forward compatibility
- Tcl_PkgPresent() forward compatibility
- Tcl_SaveResult() forward compatibility
- Tk_SafeInit() forward compatibility
- Tcl_GetErrorLine() forward compatibility
- ...
Are there other list functions which need a forward compatibility wrapper?KMG 04-Sep-05 Added lindex to the list above for the new multiple-index feature in 8.4.
AMG: I feel a good strategy for forward compatibility is to start by implementing each new feature in terms of existing Tcl capabilities (when possible, e.g. not in the case of {*}). This forms the initial reference implementation that people can start banging on quickly to determine if the interface and functionality are really a good fit. Create an exhaustive test suite for this initial version. Then port to C and/or integrate with the core. Verify the new code using the test suite, and expand the test suite to cover new corner cases as they crop up. Continue to maintain both the compatible and integrated versions so people stuck with old Tcl can fall back on the compatible version yet be reasonably assured their program will continue to work, albeit with reduced performance.One difficulty is maintaining and publishing the compatible code. I don't think this is suited to the mission of Tcllib, though a similar package specifically geared to compatibility could be created. EF mentions one above. Maybe that could be expanded. However, this compatibility library should probably be owned by the TCT since in addition to compatibility it'll also collect the initial version of experimental features before they ever get integrated with the core. Yet, this can't be part of the core Tcl repository because the whole point is being able to mix and match versions. It would work as a nested Fossil checkout in pkgs though.A more severe difficulty is {*}. Should compatibility code be written to not use it? Should compatibility code be written both ways? Should Tcl 8.4 be considered obsolete and Tcl 8.5 be the target platform? I've previously targeted 8.4 for my professional compatibility efforts, but I've been breathing much easier since allowing myself to target 8.5 instead.Targeting 8.5 isn't a panacea since I'm still without [coroutine] and [chan pipe] and half-close and other important core capabilities. This is an even bigger problem than {*} where the code can at least be rewritten to do without, yet how do I emulate [coroutine]? To me, the value of [coroutine] is the ability to [yield] through many layers of the call stack, most notably user code that I can't rewrite. [chan pipe] could perhaps be emulated with named pipes, but how would that work on Windows? And half-close emulation might require leveraging a non-Tcl intermediate process between Tcl and the process (or pipeline) actually doing the useful work, which would also be tricky on Windows. So no, this forward compatibility strategy is not always possible.