Thread overview
Timestamping as a solution to versioning hell
May 15, 2019
Alex
May 15, 2019
Ron Tarrant
May 26, 2019
KnightMare
May 26, 2019
KnightMare
May 15, 2019
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!



















May 15, 2019
On Wednesday, 15 May 2019 at 09:14:39 UTC, Alex wrote:

> It's time to make a change in the right direction!

It should also put a stop to people putting 2.10 as a later revision than 2.09, although I wouldn't count on it.
May 26, 2019
On Wednesday, 15 May 2019 at 09:14:39 UTC, Alex wrote:

> Time stamping solves all these problems.

> 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).

I agree in main point: Dlang/Libs should be versioned with using timestamp(optional) as project/compiler/dub.

RT will change. Compiler will change. Too difficult store all versions and changes in one EXE/TAR/ZIP, better use last version only and store links to known GITs servers from where it can be restored.

Next I will talk about compilers not DUB (I dont use it so dont know it). Compiler and DUB can spawn some another CLI-tool for restore RT/compiler from GITs.

- Dlang distro comes with only last version of Phobos(or other name of RT).
- Modules (should change compiler) are versioned by Major[.Minor[ExperimentalOrAlphaBetaLetter "abcde.."]] - brackets means "optional" - 2.11f
import std.xml:2.0 : someFuncsList;
We can (public) import previous version with disable something old or replaced:
public import std.xml:1.8 : disable A,B,c,d(XmlDocument); // for concrete implementation of one implementation not all of it.
Or we can write new one from scratch.
Lettered-versions used explicitly only. Or when we asked "2.0" but 2.0 doesnt exists and RT contains 2.0e for example. Lattered-version can change in future (will some bugs in compilations steps but developer takes such risks). And Unlettered-version allow not to modify code for future when release 2.0 comes.
TODO I dont remember version for aug-2017, I can setup version by date std:xml:20170805 (YYYYMMDD where month/day is optional) (some online DB or just list of GIT tags will enough?).
- All older versions are stored at GITs servers (for better accessibility lets say in 6 continents). GIT stores tagged versions. When project/compiler see some fixed date or specific version that doesnt exists in current installation it downloads its from one of GITs to some known place (for searching source/libs).
TODO compiler can changed too. how to store it: as exe (password leaks can allow malware such EXEs) or as source with compilation possibility?
- DUB/project files contains freezed/fixed date (created with "today".init and can be updated manually or interactivelly for current/specific date).
Usually u import modules without any version (I am lazy too) means "use current/last one for fixed date".
TODO what about compiler name (DMD/LDC/GDC/someNew) and version? how to store it in bin folder? dmd.2.086.0.exe?

Well, I cant to see all use-cases now and many questions will raise but IMO versioning allow compile D-code after decades without headache.
Versioning is required feature.
"experimental" named modules shouldn't be used like moveton. Coz renaming module names in written source is ugly case.

Such versioning (as described above) allow
- to forget name/version hells.
- to use same names for future/new releases.
- to re/store all versions in some known place (GITs).
- to compile any sample from github/book after any changes in compiler/RT/modules.
- other many benefits.

Those who do not remember their past are condemned to repeat their mistakes. (c) dontRememberAuthor
May 26, 2019
> import std.xml:2.0 : someFuncsList;
two colons are weird, probably need some another syntax.