"Als de definitie van een taal dikke handleidingen van honderden pagina's vereist, moet dit worden gezien als een zeker symptoom van ontoereikendheid."
Niklaus Wirth schreef dit in 1971. Hij beschreef de kenmerken van een goede programmeertaal. Zijn antwoord: een klein aantal concepten die vrij gecombineerd kunnen worden. Niet meer features. Minder. Beter.
Wirth creëerde Pascal, de taal die ik al dertig jaar gebruik. Hij geloofde dat complexiteit een waarschuwingsteken was, geen ereteken. Vijftig jaar later beslaat de React-documentatie meer dan duizend pagina's. Het TypeScript-handboek is langer dan de meeste romans. Wij doen precies het tegenovergestelde.
De paradox
Toen Wirth Oberon presenteerde, zijn laatste programmeertaal, zette hij een dia op de projector. Het toonde vier regels: de nieuwe features die ze hadden toegevoegd vergeleken met Modula-2. Toen onthulde hij de rest van de dia. Nog een dozijn regels. "En dit zijn de features die we hebben verwijderd," zei hij, met een triomfantelijke glimlach.
Features toevoegen is makkelijk. Elke ontwikkelaar kan functionaliteit stapelen. Iets opleveren, meer toevoegen, weer opleveren. De codebase groeit. De documentatie groeit. De cognitieve last groeit.
Maar weten wat je moet verwijderen vereist iets anders. Je moet het probleem volledig begrijpen. Wirth verwijderde de LOOP, EXIT en WITH statements uit latere versies van Oberon. Niet omdat hij control flow niet begreep. Omdat hij het zo goed begreep dat hij wist dat deze constructies niet essentieel waren.
Waarom we complexiteit kiezen
Complexiteit voelt als werk. Als je oplossing moeilijk te begrijpen is, lijkt het alsof je iets moeilijks hebt opgelost. Eenvoudige code voelt bijna als valsspelen. "Is dit alles?"
We verwarren "moeilijk te begrijpen" met "goed." We verwarren breedsprakigheid met grondigheid. We voegen lagen toe omdat lagen indrukwekkend lijken.
Wirth had hier een woord voor: ontoereikendheid. Wanneer iets uitgebreide uitleg nodig heeft, is het geen teken van kwaliteit. Het is een gebrek.
Code die zichzelf uitlegt
Wirth stuurde vroeger code terug naar zijn studenten als het te veel commentaar had. Niet omdat hij documentatie niet waardeerde. Omdat "de programma's dus niet helder genoeg waren."
Commentaar is vaak een symptoom, geen oplossing. Als je code uitleg nodig heeft, is de code niet helder genoeg. De beste code leest als een goed geschreven zin. Niet omdat er geen complexiteit is, maar omdat de complexiteit is doorgewerkt en opgelost.
Dit betekent dus geen slimme trucjes of cryptische oneliners. Het betekent namen kiezen die duidelijk zijn. Logica zo ordenen dat het klopt. Dingen opsplitsen tot elk deel één taak heeft.
De moed om nee te zeggen
Elke feature is een belofte. Aan gebruikers, aan toekomstige ontwikkelaars, aan jezelf. Elke feature is ook technical debt. Code die onderhouden, getest, gedocumenteerd, uitgelegd moet worden.
De moeilijkste beslissing in software is niet wat je toevoegt. Het is wat je weglaat.
Wirth wist dit. Hij wilde het goto statement niet in Pascal opnemen. Hij voegde het toe onder druk van Algol-programmeurs die zich niet konden voorstellen zonder te werken. Jaren later noemde hij het een van zijn grootste fouten. Hij had iets toegevoegd waarvan hij wist dat het niet nodig was, en de taal was er slechter door geworden.
De beste producten zijn niet die met de meeste features. Het zijn die waar elke feature ertoe doet.
Een klein voorbeeld
Neem toewijzing. In de meeste talen schrijf je x = x + 1. Wirth vond dit absurd. Het gelijkteken betekent al honderden jaren gelijkheid. Hoe kan x gelijk zijn aan x plus een? Dat kan niet. Dat is onzin.
Dus Pascal gebruikt x := x + 1. De dubbele punt-is betekent "wordt." X wordt x plus een. Eén symbool. Doelbewust. Helder.
Dit lijkt een kleinigheid. Het is een kleinigheid. Maar het laat zien hoe doordacht ontwerp eruitziet. Iemand dacht na, zag dat het niet klopte, en paste het aan.
De test
Hoe weet je of iets eenvoudig genoeg is?
Kun je het in drie zinnen uitleggen? Kun je een nieuwe collega in een uur door de architectuur leiden? Kun je het geheel overzien?
De beschrijving van Oberon paste in zestien pagina's. De hele taal. Niet alleen de syntax, maar de semantiek, het typesysteem, de modulestructuur. Zestien pagina's.
Als je systeem niet kort samengevat kan worden, wordt het misschien niet goed begrepen. Door jou of iemand anders.
Waar je eindigt
We nemen aan dat beginners eenvoudige code schrijven en experts complexe code. Het is andersom.
Beginners schrijven complexe code omdat ze niet weten wat ze kunnen weglaten. Ze voegen vangnetten toe, overbodige checks, lagen van abstractie voor problemen die niet bestaan. Ze weten niet zeker wat essentieel is, dus houden ze alles.
Experts schrijven eenvoudige code omdat ze precies weten wat ertoe doet. Ze hebben genoeg systemen gezien om te herkennen wat noodzakelijk is en wat ruis. Ze hebben het vertrouwen om te verwijderen.
Wirth liet een onuitwisbare indruk achter als iemand die eenvoud verhief en er een kunst van maakte. Niet eenvoud als luiheid. Eenvoud als het resultaat van diep begrip.
Eenvoud is niet waar je begint. Het is waar je eindigt.