We are now basically done with the restructuring and we are very happy with the result. I actually can’t stop scrolling back and forth in the new file structure, because I love so much 🙂
Unfortunately, this was only the first step before a much bigger one.
The “New” Language
The programming language used for the project is Dart. Dart is currently available in version 2. But one has decided to switch to a new version 3, which brings massive changes.
These announcements are not new for us. A year ago, I had already taken a look at what it would mean for us if we were to upgrade to the new version internally. And I immediately discarded this thought. Every single one of our approximately 1500 code files became completely unusable. The compiler simply would not build them anymore. The changes in this new version 3 of Dart are extremely massive.
In principle, Dart introduces a fundamental new concept. Programming languages, simply said, work with variables. These variables are given a value. For example, variable
A can be given the value
1. But it is also possible for a variable to have no value at all, for example because a particular calculation has not yet been performed. We are then talking about a
The more complex a program becomes, the greater the number of variables and calculations. It can then easily happen that one loses the overview here and there, whether a variable has already been provided with a value and or not. If now by mistake an empty variable is used for another calculation, say for example that
A is now used in the addition
A + B, then an error occurs because the computer does not know how to add an empty variable, a
NULL value. A so-called Null Pointer Exception occurs which immedially yields an app crash.
The new Dart version now integrates a concept called Null Safety. Internally, this makes it extremely difficult to use variables that have not yet been initialized. The change forces the programmer to pay much more attention, which leads to much cleaner and far less error-prone code.
For the techies among you: Here the concept is described in more detail.
Actually, every programmer is convinced that he always delivers the best possible code. Of course, this is fundamentally wrong. It is said that about every 1000th line of code contains a bug. That doesn’t sound much, but extrapolated to the 200,000 lines of code that the GC Wizard contains, that’s 200 bugs that could probably be found quite easily.
Well, we were refactoring the code base anyway and so we decided to try the upgrade. After the compiler version change we were shown about 4500 (!) incompatibilities. So on average three per file. It is hardly possible to set any automatisms there, each place must be subjected individually. So a much work was waiting for us here.
We had to get into old code, re-understand what it was doing, and check whether the compiler was right about the error message here. In most cases he was. It turned out that although we always try to program cleanly, we had significantly more potential bugs – places where we might have accessed empty variables – than just in every 1000th line. I estimate I found 1000 actual dramatic bugs by myself, Mike probably more. Some of these bugs could be fixed quickly, but for some we had to go deep into the code, sometimes even rethinking and rewriting whole files.
The Actual Problem
Now you can certainly imagine that if you have to edit 4500 places, you quickly lose the overview. With the normal development one changes a place, starts the program and looks whether everything still functions as expected. But here we face the problem that the compiler is constantly complaining. As long as only one place is marked incorrect, we will not be able to start the program. That means, we cannot look after a single change, if the error correction was successful. We work in blind flight.
Only when all marked areas are eradicated, we can start the app again and see if everything still works. Although we are absolutely mindful of what we are doing, it is certainly easy to imagine that new bugs have crept in, especially with the larger necessary changes. We will know in a few days.
What Happens Next
We have already made good progress with the error locations. However, I have to admit that we lost track of which of the thousands of places required major changes and which were trivial. We are forced to put the entire app through its paces. Every single tool has to be tried out. Every single input field has to be checked and fed with all kinds of different data. Does everything still work as expected?
Automated tests can help us with many things. This is especially true for the logic, i.e. the internal calculations of the functions. But what we can hardly automate are the graphical user interfaces: Does this text field really only accept digits? Does that drop-down menu still work with all entries?
Here we will need massive help from everyone who can give. We’re working on a test plan right now that everyone will be able to see. We’re currently discussing internally within the team whether it might make sense that we don’t just release a new update, but a new temporary app just for testing. “GCW 3.0 Beta” or something like that. Simply to avoid that the upcoming update overwrites your actually working app and maybe some tools don’t work anymore.
Who wants to support us? 🙂