Vergeet programmeertalen, lang leve de compiler
Welke programmeertalen spreek jij? En hoe belangrijk is dat? Op het einde van de rit probeer je immers met een computersysteem te spreken, en de hardware snapt even weinig van C# en Java als van Python of R. De computer waarvoor je programmeert, begrijpt maar één ding: machinetaal of binaire code.
1. 0 en 1 of Hello World
Gelukkig hoef je vandaag geen machinetaal te kennen om te programmeren. Code schrijf je in een high level-taal die vervolgens vertaald wordt naar het niveau van de machine. Print (‘Hello World’) is immers significant eenvoudiger om te typen dan een sequentie van nulletjes en ééntjes.
Verschillende talen hebben verschillende objectieve en subjectieve voordelen. Zo is het overal. Engels lijkt geschikt voor internationale communicatie in luchtvaart, Frans heeft de woordenschat voor de liefde in pacht. In het geval van computers heb je, ongeacht de taal die je kiest, een vertaler nodig. Die vertaler zet je werk om in ééntjes en nulletjes, en daar gebeurt de magie.
2. Zwijgen en vertalen
Vandaag krijgt de compiler misschien niet meer de liefde die hij verdient. De programmeur schrijft code, de compiler klaagt niet, en de wereld is mooi. De tool doet wat hij moet maar niemand vraagt zich af wat er achter de schermen gebeurt.
De compiler werd uitgevonden door Grace Hopper. Zij is er rechtstreeks verantwoordelijk voor dat je in verschillende variaties van Engels programma’s kan neerpennen die uiteindelijk op een veelvoud van binaire systemen draaien.
Compilers maken of kraken ecosystemen. Het is de compiler die beslist of je code vlot kan draaien op x86-systemen, ARM-smartphones of RISC-V-servers. Dankzij de compiler kan jij in je favoriete taal schrijven en ontstaat er aan het einde van de werkdag een uitvoerbaar bestand dat op verschillende systemen werkt. Is de compiler een slechte tolk die jouw mooie algoritmes naar trage code vertaalt? Dan zal de taal of de hardware waarmee die compiler verbonden is een stille dood sterven.
3. Samenstelbaar
Compilers vandaag hanteren doorgaans dezelfde structuur. Ze bestaan uit drie belangrijke delen: de front-end, de optimalisatie en de back-end. De front-end leest je code en zorgt voor een eerste rudimentaire vertaling. Die doorgaat vervolgens een optimalisering, om tot slot door de back-end nogmaals herwerkt te worden tot precies het juiste formaat voor het systeem waarvoor je compileert.
De drieledigheid is essentieel voor het succes van moderne ecosystemen. De moduleerbaarheid van een moderne compiler betekent dat je enkel de front-end moet aanpassen wanneer je een nieuwe programmeertaal op een bestaand ecosysteem wil introduceren. Of andersom kan je een compiler voor een bepaalde taal herwerken voor een nieuwe binaire architectuur gewoon door de back-end aan te passen.
4. Post-Von Neumann
Dat is vandaag belangrijker dan ooit. Het tijdperk van de Wet van Moore, de heerschappij van x86 en bij uitbreiding de Von Neumann-architectuur is voorbij. Er zijn natuurkundige limieten aan de kloksnelheid en transistordichtheid van chips en die komen stilaan in zicht. De oplossing langs de hardwarekant is een heterogene compute-architectuur.
Dat betekent voor een stuk dat je de juiste architectuur voor de job gebruikt (zoals ARM voor mobiele toepassingen), maar ook dat je combineert. Een processor wordt vandaag bijgestaan door een GPU, een DPU en misschien nog een FPGA die een specifieke functie accelereert.
5. Een beetje liefde
Hoe eenvoudig het zal zijn om voor die heterogene systemen te programmeren, is voor een groot stuk in handen van de compilers. De nieuwe hardware zal niet meteen zorgen voor de geboorte van een nieuwe taal die alle andere vervangt. Bestaande talen blijven populair en nieuwe zullen ontstaan, maar om een succes te zijn moeten ze overweg kunnen met een veelvoud aan hardware. Modulaire compilers gaan dat mogelijk maken, en verdienen daarom af en toe een beetje liefde.
Is jouw liefde voor compilers (bijna) even groot als die voor programmeren? Bekijk onze vacatures of stuur vandaag nog een open sollicitatie.