| |
| Posted by Alex | PermalinkReply |
|
Alex
| The problem with versioning is that two different entities do not version in a way that correlates to a working state:
E.g., take two modules. As they are revisioned, the correlation between the revisions is not recorded by versions. If anything breaks between through interrelated issues, it cannot be tracked by versioning.
Time stamping solves all these problems.
Proper rule to handle all versioning issues - Do not use versioning. Use time stamping and immutability:
An entities life time is a function of t, f(t), a history, or a github repository change long, so to speak.
Changes happen in time, we can't change the past, but we can screw up the future.
By having all changes time stamped, if any state at some time t is known, and all future changes do not effect past changes(immutability) then the state at some time t is stable/fixed/immutable.
For example, if I create a program and it worked perfectly at time T AND time stamping/immutability was done perfectly then I could always know that my program worked by simply rolling back to time T.
That is, imagine all D modules and compiler's time stamped when "changed"(not breaking changes don't have to modify the time stamp). All previous history is recorded(kept).
Now, suppose I have a working program at some time, say 2019.05.05. All dependencies that it uses also work because the program works.
Now, suppose it is 2050.0.0 and I want to get my program to work! It will almost surely fail because all the modules have "changed".
But if I, say, could specify to use all the modules up to 2019.05.05 then I'd get the original modules that were used at that time and every would work because I'd be using the exact same state as before[Obviously things might change, such as OS, hardware, etc... but ultimately that would have a time stamp too and everything would work.. but that is not practical, we are just trying to minimize the problems].
-UseVer2019.05.05
would essentially limit to using all the modules up to that date... which was the date that the program compiled and hence all the code should be identical(any changes to modules after that would not be used and hence could not break anything).
Then a dustmite solution could be used where the compiler will increase the date(could use binary search) to find the largest date that still compiles the source(could check binary difference for regression like effects).
E.g., maybe it will download the modules up to 2020 and then an error occurs after.
-UseVer2020.0.0
works but after it fails.
The error could be reported and the module that produces it could be rolled back and specific changes in the module could be shown that caused the failure(a diff between the working module and the failed one).
The user then could handle the issue.
I'm only giving a outline of how it would work... but it should be clear that versioning is meaningless but time stamping solves these problems!
It should have been done from the start, it wasn't, and it has created a lot of grief.
Time stamping and immutability correlates all modules with time while versioning does not. With versioning we have to keep track of all the different versions of modules to make sure our program works... a total PITA.
With time stamping, we just have to remember which was the last day our program worked(which we can guess, use a search, or just look at a time stamp on the exe or source code).
If you agree that this is a much better solution, it then requires implementation details:
----------------------------------------------
1. All entities: modules, tools, compilers must be time stamped in an effective way. For modules this should be in the name itself. The current non-time stamped names are aliased to the most recent modules by default. (e.g., using -UseVer99999.0.0)
2. All breaking changes to entities produce a new time stamped entities. Everything is stored in a proper hierarchical database so any entities of any time stamp can be retried.
3. Any non time stamped module is time stamped as coming from 1000.0.0. Hence, if D was to switch over to time stamped versioning all current entities are set at 2019.05.15 and any new changes will be time stamped > 2019.05.15
4. The compiler itself is modified to handle this new information. One can set the compiler to use a specific time stamp, to download entities that are needed/requested(the lasted are always included but if one requests older ones then it download it, even including the compiler).
Having such a system allows anyone to get back to a working state no matter what. Since everything is immutable it means that that the history always exists and if a program worked at previous point it can work at some time in the future because that previous point can be retrieved.
Versioning as we know it will go away.
Upgrading a program is simple and easy and one can always upgrade to the latest modules that work and then push through from entities that don't by either forcing the entities to use older versions or correcting the code.
One could have a nice method of showing the issues and even a graphical method that shows the dependency graph in time and where things go wrong.
Time is the key, arbitrary versioning is not. Version numbers record nothing but that a change occurred, they do not tell one anything about when the change occurred... knowing when a change occurred is important and time stamping synchronizes ALL changes across the universe. Immutability allows us to go back and recover the state.
It's time to make a change in the right direction!
|