Sunday, April 16, 2017

Why don't you just rewrite it in X?

Whenever a new programming language becomes popular its fanpersons start evangelizing its virtues by going to existing projects and filing bug reports that look like this.

Hi, I noticed that this project is written in [programming language X]. You really should just rewrite it in [programming language Y] because it is better at [some feature Z]. Kthxbye!

When put like that this seems like a no-brainer. Being better at Z is good so surely everyone should just port their projects to Y.

Recently there has been movement to convert tooling used by various software projects in the Gnome stack from a mishmash of shell, Awk and Perl into Python 3. The main reasoning for this is that having only one "scripting" dependency to a modern, well maintained project makes it simple to compile applications using Gnome technologies on platforms such as Windows. Moving between projects also becomes easier.

One tool undergoing this transition is GTK-doc. which is a documentation generation tool written mostly in Perl. I have been working together with upstream to convert it to Python 3. This has been an educational experience in many ways. One of the first things learned is that converting between any two languages usually breaks down to three distinct phases.

  1. Manual syntax conversion
  2. Fixing bugs caused by conversion errors
  3. Converting code to idiomatic target language

A Perl to Python conversion is relatively straightforward in the case of gtk-doc. It mostly deals with regular expressions, arrays and dictionaries. All three of these behave pretty much the same in both languages so step one is mostly manual work. Step two consists of fixing all the bugs and behavioural changes introduced in phase one (many caused by typos and lapses of concentration during step one). This phase is basically debugging. The third step is then a question of converting regular expressions and global variables into objects and other sane and readable constructs.

When doing the conversion I have been mostly focusing on step one, while the gtk-doc maintainer has agreed to finalize the work with steps two and three. While converting the 6000+ lines file gtkdoc-mkdb, I did some measurements and it turns out that I could do the conversion at a peak rate of 500 lines an hour, meaning roughly 7 seconds per line of code.

This was achieved only on code that was easy to convert and was basically an exercise in Emacs fingering. Every now and then the code used "fancy" Perl features. Converting those parts was 10x, 100x, and sometimes up to 1000x slower. If the port had required architectural rework (which might happen when converting a lax language to one that has a lifetime checker in the compiler, for example) it would have slowed things down even more.

I don't know how much work steps 2 and 3 entail, but based on comments posted on certain IRC channels, it is probably quite a lot. Let's be generous and say overall these three items come to 250 lines of converted code per hour.

Now comes the truly sad part. This speed of conversion is not sustainable. Manually converting code from one format to another is the most boring, draining and soul-crushing work you can imagine. I could only do this for a maximum of a few hours per day and then I had to stop because all I could see was a flurry of dollar signs, semicolons and curly braces. Based on this we can estimate that a sustained rate of conversion one person can maintain is around 100 lines of code per hour (it is unlikely that this speed can be maintained if the project goes on for weeks but since there are no measurements let's ignore it for now).

The cURL project consists of roughly 100 thousand lines of C code according to Ohloh. If we assume that converting it to a some other language is just as easy as converting simple Perl to Python (which seems unlikely), the conversion would take 1000 person hours. At 8 hours per day that comes to around 5 months of full time work. Once that is done you get to port all the changes made in trunk since starting the conversion. Halting the entire project while converting it from one language to another is not an option.

This gives us a clear answer on why people don't just convert their projects from one language to another:

There is no such thing as "just rewrite it in X".

Post scriptum

There are tools that automatically convert from one language to another. They can help, but only in step one. Steps two and three are still there, and could take more work than manually converted code because usually manual conversion produces more human-understandable code. Sadly Turing-completeness says that we can't have nice things.

Thursday, April 13, 2017

How Meson is tested

A build system is a very important part of the development workflow and people depend on it to work reliably. In order to achieve this we do a lot of testing on Meson. As this is mostly invisible to end users I thought I'd write some information about our testing setup and practices.

Perhaps the most unconventional thing is that Meson has no unit tests in the traditional sense of the word. The code consists of functions, classes and modules as you would expect but there are no test for these individual items. Instead all testing is done on full projects. The bulk of tests are what could traditionally be called integration tests. That is, we take an entire project that does one thing, such as compile and install a shared library, and then configures it, builds it, runs tests and runs install and checks that the output is correct.

There are also smaller scale tests which are called unit tests. They also configure a project but then inspect the result directly. As an example test might set up a project and build it, and then touch one file and verify that it triggers a rebuild. Some people might claim that these are not unit tests either or that they should instead be tested with mock classes and the like. This is a valid point to make, but this is the terminology we have converged unto.

Enter The (Testing) Matrix

Our testing matrix is big. Really big. At its core are the three main supported platforms, Linux, Windows and OSX. We also support BSD's and the like but we currently don't have CI machines for them.

On Windows our Appveyor setup tests VS2010, 2015 and 2017 and in addition mingw and Cygwin. Apart from Cygwin these all are tested on both 32 and 64 bits variants. Visual studio is tested both with the Ninja and Visual Studio project generator backends.

OSX is the simplest, it is tested only with the Ninja backend using both regular and unity builds.

Linux tests do a lot more. In addition running the basic tests (both in unity and regular modes) it also runs the entire test suite in a cross compilation setup.

All of these tests are only for the core code. Meson supports a large amount of frameworks and libraries, such as GLib, Qt and Doxygen, and many programming languages. Every one of these has an associated test or, usually, several. This means that running the full test suite on Debian requires installing all of these:
  • Boost
  • D, Rust, Java, Fortran, C# and Swift compilers
  • Qt 5, WxWidgets, GTK+ 3
  • Valgrind
  • GNUstep
  • Protocol Buffers
  • Cython
  • GTest and GMock
And a bunch of other packages as well. The CI Docker image that has all of these installed takes 2 gigabytes of space. On many distros all dependencies are not available so packagers have to disable tests. Having a build dependency on all these packages sometimes yields interesting problems. As an example the Rust dependency means that Meson depends on LLVM. Every now and then it breaks on s390x meaning that Meson and every package that uses it to build get flagged for removal from Debian.

Every merge proposal to Meson master is run through all of these tests and is eligible for merging only if they all pass. There are no exceptions to this rule. 

There are some downsides to this, the biggest being that every now and then Appveyor and/or Travis get clogged and getting the green light takes forever. We looked briefly into getting paid instances but for our usage the bill would be in the neighborhood of $300 per month. Given that you can buy your own hardware for that kind of money, this has not been seen as a worthwhile investment. 

Saturday, April 8, 2017

Meson project status update

The text below is a copy of this post to the Meson development mailing list.

Hello everyone

The last few weeks have been an amazing ride for the Meson project. We
have gone from "interesting but niche" to being seriously considered
for such core infrastructure projects as Mesa, Wayland, Xorg and even
systemd. I would like to thank everyone who has contributed in making
this possible. Thanks to all contributors, evangelists, those who have
converted their projects, or even proposed it. We would not be here
without you.

However having this much growth brings with it new problems. The main
one of these, as most of you have probably noticed, is the growth in
pull request backlog. I know there are MRs that have been waiting for
quite a while and that this is very frustrating to those people who
have filed them. My apologies to you, we are trying to make this
better.

The second issue is the perennial problem of documentation.
Interestingly these two issues are quite tied together in unexpected
ways.

One of the things which is taking a lot of time for me personally is
making sure that all the documentation is up to date after merge
requests are done. This is a major problem and is limiting the number
of changes that can go in.

We have examined various ways of solving this problem. We have a PoC
for moving all documentation away from the Github wiki and inside the
main repository. This way we can require that all merge requests come
with corresponding documentation changes. This would reduce the review
burden.

A preview of the site can be seen here: http://mesonbuild.com/experimental/

The downside of this approach is that we would lose the ability to do
in-browser wiki editing, and even typo fixes would need to go via pull
requests. This is unfortunate. There does not seem to be a solution
that would work for both use cases. Final decisions on this have not
been made, so if there are people who have good suggestions or prior
experience with this, please speak up.

There are many other ways to help, too. Thus far I have done a large
fraction of, well, everything, ranging from bug reports to review to
designing new features and helping people on the mailing list. All of
these activities are fun and interesting, but there is only so much
time and I feel I'm already spreading myself too thin. This causes
problems such as the above mentioned backlog of merge requests.

We already have a wonderful group of people doing great work on IRC
and elsewhere. Thank you all for your efforts. But the fact of the
matter is that if the project continues seeing more uptake, we are
going to need more helpers, especially reviewers. Currently this task
rests almost entirely on me and Nirbheek. Any help on this would be
greatly appreciated. Just going over the code and saying "based on a
cursory glance this seems ok" would be helpful.

The one elephant in the room is that currently only I have merge
access to master. This is an obvious bottleneck, but if we manage to
fix the other issues listed above it should not be a limiting issue.
Still, if usage and contributions keep growing, we might consider a
multi-maintainer mode. The project is now large enough that we can
have subsystem maintainers, much in the same way as in the Linux
kernel. Example of these could include Windows maintainer, Gnome tools
maintainer, Qt maintainer, Android maintainer, documentation
maintainer and so on. A different approach would be to just have more
people with commit access and allowing them to move around the code as
they have interest. If you have experience or knowledge on how to best
handle this, please let us know.

Thank you all, and keep on compiling!

Tuesday, April 4, 2017

Inspector Gadget as an allegory of software engineering profession in the modern age

Many people think that Inspector Gadget is a quirky 80s animation series about a bumbling, but well meaning cyborg police inspector fighting an evil organization called MAD. This is not true. In reality the show is an allegory about the day to day work life in a modern software development company. It tells this story with foresight and accuracy that rivals, and sometimes even exceeds, Silicon Valley and its ilk.

This may seem like a bold claim, but let's us examine a typical episode and we shall see how facts stand firmly by this assertion.

The rockstar coder

The supposed hero of this series is Inspector Gadget himself. At the beginning of every episode he is spending his free time and is then unexpectedly called into work. Some sort of disaster has struck and he is the only one who can fix it. The Inspector then says Don't worry, chief, I'm always on duty and heads off.

From this simple exchange we know that the Inspector is the hotshot rockstar developer. The Ninja! The Cowboy Coder! The man who has no concept of work-life balance! He drops whatever it is he is doing and goes off to solve the problem.

Once at work we quickly discover that he is more than a rockstar. He is, in fact, an incompetent fool who thinks he is the greatest thing ever. During the course of the entire show, Inspector Gadget does not manage to make a single thing better. All he does is run around from one place to another and try arbitrary things that are not in any way helpful or even rational. Examples include swinging a mallet around randomly (while breaking expensive pieces of arg), inflating his coat for no rhyme or reason (usually knocking innocent people over) or even helping the bad guys perpetrate their crimes because they just ask for his help.

At no point does anyone call Inspector Gadget out for clearly being a useless idiot who only does harm. The entire organisation would work more efficiently if he was kicked out. But yet he remains, having reached a high enough level on the police force's organisation chart that he can't be fired, or even challenged.

The firefighter

The second person in our group of people is not actually a person, but a dog. Brain is the pet of Inspector Gadget. Whenever the inspector heads off to solve a case, Brain is given the same task: follow Inspector Gadget around and fix everything he breaks.

Here we find the only major disparity between Inspector Gadget the series and real life. In the latter, the incompetent rockstar (also known as Senior Systems Architect) breaks so many things that it takes more than one person to fix them. In extreme cases the group can consists of every other developer in the company. Perhaps this is the reason why Brain is portrayed as a dog. He does not represent a single person, but all of them.

If ew observe how Brain fixes the Inspector's bumblings, a common pattern arises. He always has to fix things in a way that the Inspector does not notice anything. Presumably if he were to notice these fixes, he would go back and change things back the way he left them. That is, completely broken.

Brain never does anything else, his life is a continuous stream of fighting fires that should never have been set alight. An illuminating example of this is the "pineapple incident" in episode Volcano Island, between 13m 54s and 14m 45s.

The fixer

The task of actually solving all problems is left to Penny, Gadget's niece. She does not fool around with pointless Rube Goldberg gadgets. She is highly competent and efficient in solving any problem. In an average episode Penny spends less than five minutes looking at the problem, finding the root cause, fixing it and wrapping everything up. She is a competent and smart person with solid engineering and problem solving skills. She single handedly thwarts MAD and is the main reason the entire world does not fall into anarchy.

Penny is never given any credit for this. In fact whenever she tries to talk some sense to the other characters, she is actively dismissed and belittled. Once the case is solved everyone goes to Inspector Gadget and congratulates him for doing a good job. The Inspector replies with something like I solved the case? I guess I did. Like any incompetent rockstar he is willing to take all the praise without doing any of the work.

In light of this it should be obvious why the character of Penny is a woman.

The wild card

The final person in this gallery is Dr. Claw, the leader of MAD. During the course of the show he does only two things. One: he looks at live video streams on his computer while scratching a cat. Two: he complains that everything done by everyone else is wrong (while never doing anything himself).

There are two differing theories on what he is supposed to represent. The first claims that he represents the company founder/owner who struck gold but since then has lost grasp of the present and just lashes out to his underlings at random.

The other theory claims that the creators of the show were incredibly foresighted and created Dr Claw as a prototype of modern day internet trolls 25 years before they actually appeared.