Waarom C de beste programmeertaal is

Of: waarom C nooit zal verdwijnen

Ik ken Lua, Python, php, SQL, javascript, Rust, en C. En er is niets zoals C.

Simpel

De grote kracht van C is hoe simpel de taal is. In plaats van uren zoeken naar de beste manier om xyz te doen, doe je het gewoon. Je leert in een week de syntax, en gaat ermee aan de slag. Waar je in Python niets snapt omdat je de enorme taal niet volledig kent, snap je in C niets omdat je simpelweg het algoritme niet snapt. In die zin is C puurder.

Daar staat tegenover dat C een magere taal is: veel functies die in andere talen ingebouwd zijn zul je zelf moeten maken. C++ is hier een oplossing voor, excessief zelf. Zelf denk ik dat de juiste balans ergens tussen C en C++ in ligt.

Compiled

Met die simpliciteit geeft C vrijheid aan de programmeur. Tegelijk voorkomt de compiler en het typesystem dat je domme fouten maakt. In scripttalen loop ik extreem vaak tegen typfouten aan, die dan pas in runtime worden ontdekt. Dit zorgt ervoor dat je ellenveel tests moet schrijven en dat QA in het algemeen een irritant proces is. De compiler verhelpt dit soort fouten, zelf zet ik hem het liefst op allerstrengst.

Type system

C heeft dus ook een type-systeem, iets wat veel talen niet hebben. Die talen hebben dan het probleem dat je maar net moet onthouden wat een functie nam. Neemt f() een array, een object, of een getal? In C weet je het direct, maar in php, js, python, lua moet je gokken of constant bladeren.

Abstracties

Voor veel talen staan abstracties helaas gelijk aan inperking: je wordt een bepaalde weg geboden waardoor je sommige dingen niet of amper kan doen, of niet kan uitdrukken op een natuurlijke manier. Zo heeft het meer functional-programming smakende Rust bijvoorbeeld geen for(x;y;z) loops. Maar abstracties hoeven niet tot inperking te leiden, laat C zien. C heeft de meest krachtige abstractie van hen allemaal: pointers. Geheugenadressen.

Vrijwel elke variabele komt ergens in het computergeheugen terecht. Je kan er dus bij met een pointer.

Arrays? Arrays zijn gewoon een verzameling van blokjes data. Achtereenvolgend. Beginnend op een bepaald geheugenadres. Wacht eens, arrays zijn pointers! En strings zijn pointers!

Wat zijn functies? Wanneer je een functie callt, wordt er op de stack wat ruimte gemaakt voor de variabelen in de functie, en wordt er een jump instructie (of iets vergelijkbaars) uitgevoerd door de processor. De processor slaat een aantal bladzijden om, en begint nu met het lezen van machinecode beginnend vanuit een ander bepaald geheugenadres. Oh! Dus functies zijn ook pointers!

Alles is een pointer. Alles is een first class citizen. Pointers zijn de ultieme abstractie.

De haken en ogen

Oké, oké. De perfecte taal bestaat niet. En zo heeft ook C haken en ogen: memory management is lastig. Je kan nog zulke goede regels voor jezelf opstellen, maar toch blijkt het onmogelijk om het in één keer perfect te doen. Waar je in scripttalen een runtime crash krijgt vanwege een typfout, krijg je in C een runtime crash vanwege een segmentation violation. Beide zijn even irritant, en beide zijn op zich triviaal op te lossen.

Wat verraderlijker is, is de string library die C biedt. In C is een string gedefinieerd als een array van letters die doorgaat tot je een NUL-character raakt. Keer op keer wordt bewezen in het wild dat dit een enorm slecht idee is. Buffer overuns, kwadratische O() performance vanwege scanf(), noem het maar op. Dit is een van de weinige dingen die ik aan zou passen aan C, want strings zijn nou net het enige waar scripttalen juist meer vrijheid van uitdrukking aan de programmeur bieden.

Ten slotte error handling. C doet dit absoluut niet goed. Het is veel extra werk om je errors te checken, en bij veel talen hoeft dit niet omdat alles weggewerkt zit in één veilige, simpele functie. Daarnaast worden er vaak betere manieren aangeboden om met fouten om te gaan, zoals exceptions.

Conclusie

Kortom, C is als een katana. Een bescheiden wapen dat op het oppervlak misleidend simpel lijkt, maar een zeker mate van meesterschap verreist voor effectief gebruik. C beloont hard werk en slim denken. Ja, er zijn talen die meer op een AK-74 lijken of zelfs een bazooka, maar geef het maar toe: de eenvoud, de snelheid, en de vrijheid van C is niet te verslaan. Heel even werd ik verleid door Rust, maar Rust maakt het toch weer te ingewikkeld, toch weer te ingeperkt.

2021-04-19 in blog #C #Rust