Pieter Edelman
31 January

In 2014 concludeerde een analyse van opensourceprojecten op Github dat de gebruikte programmeertaal een kleine, maar meetbare invloed heeft op de hoeveelheid bugs. Maar dat is te kort door de bocht, stelt een groep computerwetenschappers nu.

Het is een eeuwig terugkerende discussie: heeft de gebruikte programmeertaal een effect op het aantal bugs in de resulterende software? Softwareontwikkelaars voelen het wel aan hun water dat bepaalde keuzes in een taal makkelijker fouten uitlokken, maar dat is lastig hard te maken. Het impliciet omzetten van types maakt het wellicht makkelijker om een fout te maken, maar leidt dat ook tot meer bugs in de productiecode? Misschien gaat het codekloppen wel zo veel vlotter dat er meer tijd overblijft om de fouten eruit te filteren.

In 2014 bedacht een groep Amerikaanse computerwetenschappers dat ze dit makkelijk konden meten aan de hand van de vrij beschikbare broncode in opensource-repository’s. Omdat softwareontwikkelaars er de laatste jaren aan gewend zijn geraakt alles netjes in een versiebeheersysteem te stoppen, konden de commit-beschrijvingen netjes worden doorplozen op termen als ‘bug’, ‘fix’ of ‘defect’, waarmee een duidelijke relatie kon worden gelegd tussen de programmeertaal van het project en het aantal bugs.

Hun conclusie: de taalkeuze heeft een kleine, maar meetbare invloed op het ontstaan van problemen. C/C++, Javascript, PHP en Python zijn foutgevoeligere talen, Typescript, Clojure, Haskell en Scala juist robuust, bleek uit een studie onder 728 projecten op Github. Of algemener gezegd: automatisch geheugenbeheer, static typing en functioneel programmeren zijn belangrijke aanpakken om bugs te reduceren. In 2017 kreeg de studie een update, met dezelfde conclusies.

Beter tellen

Maar dat is te kort door de bocht, claimt een vijftal computerwetenschappers uit Amerika en Europa nu. Ten eerste wijzen ze erop dat een verband tussen taal en bugaantallen nog niet wil zeggen dat de taal ook de oorzaak is. Maar ze zetten ook zo hun vraagtekens bij de analyse zelf. Toen ze het onderzoek nog eens goed tegen het licht hielden, vonden ze aanzienlijke fouten.

Met name de interpretatie van de commits was dubieus. Heel veel beschrijvingen lijken met een simpele analyse op bugfixes, maar zijn dat helemaal niet – de beschrijving ‘better error messages’ bijvoorbeeld. Uiteindelijk bleek meer dan een derde van de gevonden bugmeldingen zo onterecht te zijn. Daar stond tegenover dat elf procent van de fouten juist werd gemist.

Daarnaast bleek dat een deel van de inputdata vervormde resultaten opleverde. Voor C++-projecten werd bijvoorbeeld niet gekeken naar headerbestanden, terwijl die ook code kunnen bevatten. De bestandsextensie .ts wordt niet alleen gebruikt voor Typescript, maar ook voor tekstvertalingen. En de V8-Javascript-engine bevat wel voornamelijk Javascript-commits, maar is geschreven in C++.

Bovendien hadden de oorspronkelijke auteurs de nodige statistiekblunders begaan. Als al die overwegingen worden meegenomen, blijft er weinig over van de correlatie. De belangrijkste vinding van het oorspronkelijke werk was dat maar liefst elf van de zeventien onderzochte programmeertalen een significant effect bleken te hebben op de codekwaliteit, maar in het nieuwe werk blijven daar nog maar vier van over (C++ negatief, Clojure, Haskell en Ruby positief). Het effect is bovendien ontzettend klein.

In de oorspronkelijke studie trekken de onderzoekers hun gevonden effecten door naar de algemene ideeën achter een taal. Omdat Haskell bijvoorbeeld een functionele taal is en geassocieerd wordt met minder bugs, worden functionele talen als robuuster beoordeeld dan procedurele of scriptingtalen. Zo werden er nog drie verdelingen gemaakt: statische (gecompileerde) talen versus dynamische, sterke tegen zwakke types, en automatisch of handmatig geheugenbeheer.

Maar ook daar heeft de nieuwe studie kritiek op. Maar al te vaak past een taal helemaal niet goed in een bepaalde categorie. ‘Scala wordt bijvoorbeeld gecategoriseerd als functionele taal, maar laat het ook toe om programma’s op een imperatieve manier te schrijven. We kennen geen studies die aantonen dat Scala-gebruikers voornamelijk functionele code schrijven. In onze ervaring mengen ze deze twee vormen veelvuldig’, schrijven de auteurs.

Zo zijn er meer grijze gebieden. Python, Ruby, Clojure en Erlang hebben een sterk typesysteem, maar kunnen ook min of meer zwakke types gebruiken. En Objective-C wordt gecompileerd, maar bevat ook dynamische elementen. Er moeten dus meer categorieën worden toegevoegd, en dan verdwijnen de gevonden effecten ook.

Haken en ogen

Hoe verder je inzoomt op de dataset, hoe meer vraagtekens er te plaatsen zijn, stellen de auteurs. Moet testcode bijvoorbeeld worden meegenomen in de analyse? ‘Testcode verandert regelmatig om zich aan te passen aan wijzigingen in api’s, om nieuwe tests toe te voegen, et cetera. De commits kunnen wel of niet relevant zijn, want bugs in testcode kan heel anders zijn dan in normale code. Bovendien kan het meenemen van tests leiden tot dubbeltelling van bugs (de bugfix en de test kunnen twee afzonderlijke commits zijn)’, schrijven ze.

Er moet ook beter worden gekeken naar de selectie van de projecten. Het PHPDesignPatterns-project zou bijvoorbeeld qua omvang en populariteit meegeteld moeten worden, maar bestaat eigenlijk alleen uit voorbeeldcode. En in volwassenere projecten komen verhoudingsgewijs minder bugs voor, wat betekent dat oudere talen als veiliger kunnen worden gezien. De vraag is ook of Github-projecten wel representatief zijn. Zeker als het hobbyprojectjes zijn waar een enkele programmeur achter zit, zouden ze best kunnen afwijken van industriële softwarebouwwerken.

Betekent dat dat de programmeertaal geen invloed heeft op het voorkomen van bugs in de uiteindelijke code? Die conclusie durft de nieuwe paper ook weer niet te trekken. De auteurs zeggen alleen dat hun overwegingen moeten worden meegenomen in vervolgonderzoek. Maar het effect in de oorspronkelijke studie was al niet groot en wordt alleen maar kleiner na een grondige heranalyse. Het lijkt er in elk geval op dat foutgevoeligheid geen belangrijkere overweging hoeft te zijn dan productiviteit, beschikbaarheid of lol van een taal.