Wat agents betekenen voor Rust (en vice versa)

Om je niet in spanning te laten, geef ik direct de conclusie. Kort gezegd: ja, ik geloof dat er nog steeds een rol voor mensen zal zijn in programmeren. En ja, ik denk dat het ontwerpen van programmeertalen nog steeds relevant is. Bovendien denk ik dat Rust bijzonder goed past bij agentische ontwikkeling — maar dat betekent niet dat we het niet nog beter passend kunnen maken. Dat is waar dit bericht uiteindelijk over gaat: wat maakt dat Rust en agentische ontwikkeling goed samenwerken, en waar kunnen we die sterke punten verder uitbouwen?

Dit is een soort "blog-begeleidende versie" van een presentatie die ik deze week gaf op REBASE, onderdeel van SPLASH. In elk geval was het een geweldige conferentie! Jack Huey presenteerde over het Rust Vision Document en, tot mijn verbazing, presenteerden Steve Klabnik en Dorian Scheidt "LLMs as Collaborators in Language Specification and Design", waarin ze spraken over hun proces bij het bouwen van Rue. Daarnaast werd er veel geweldig onderzoek gepresenteerd bij IWACO, waarbij ik vooral onder de indruk was van het werk over Reachability Types en Information Borrowing, en de aanpak van projecties in de taal Hylo.

Rust is populair in het agentische tijdperk

Rust is momenteel erg populair.

"Tussen de talen met de grootste groei is TypeScript het meest opvallend, die momenteel een groei van +1200% vertoont ten opzichte van het voorgaande jaar. [...] De tweede snelste groei is te zien bij Rust. Meta-engineers hebben dit jaar al twee keer zoveel eigen Rust-code geschreven als in de voorgaande 9 jaar gecombineerd."
— David Tolnay

Een deel hiervan komt doordat agents het heel gemakkelijk maken om nieuwe dingen uit te proberen. Daarnaast heeft Rust een reputatie voor hoge prestaties; als het net zo makkelijk is om elke willekeurige taal te kiezen, waarom dan niet kiezen voor een taal die snellere executietijden oplevert?

Maar ik denk dat Rust populair is om een andere reden: Rust blijkt simpelweg een zeer goede match te zijn voor agentisch programmeren[^6]. Het doel van dit bericht is om te beargumenteren waarom dat zo is en te bespreken wat we aan Rust zouden kunnen veranderen om het nog beter te laten werken.

De fundering van softwareconstructie met agents

Het lijkt me dat een effectieve "softwarefabriek" uit drie pijlers bestaat:

  1. Ontwerp: bepalen en duidelijk specificeren wat de code moet doen.
  2. Constructie: code schrijven die doet wat er van verwacht wordt.
  3. Optimalisatie: de code optimaliseren zodat deze efficiënt draait.

Geen van deze pijlers is volledig "opgelost", maar sommige hebben meer vooruitgang geboekt dan andere.

Rust en optimalisatie: standaard snel, met knoppen waar nodig

Rust is ontworpen om "standaard goede prestaties" te leveren, waardoor de idiomatische manier van programmeren meestal ook de snelste is. Een ander essentieel onderdeel van Rust is dat je "knoppen" hebt om nog betere prestaties uit de code te persen wanneer dat nodig is. Je hebt controle over wanneer iets op de stack of de heap wordt gealloceerd en waar pointer-indirectie optreedt. Je kunt de layout van structs forceren of beslissen waar je boxing introduceert in je async stack frames. In het uiterste geval kun je inline assembly toevoegen.

In het verleden kon het leren hoe je deze prestatieknoppen moest afstellen een soort zwarte kunst zijn, maar agents maken dat veel gemakkelijker[^7]. Het blijkt dat agents zeer goed zijn in het fijn afstellen van de prestaties van bestaande code. Mensen die werken aan cryptografische algoritmen met extreem hoge prestaties, deden dit voorheen handmatig in assembly; zij vertellen me nu dat ze agents voor diezelfde taak inzetten. Meer alledaags: veel mensen die netwerkdiensten bouwen, merken dat agents, in combinatie met een profiler zoals dial, effectief async-prestatieproblemen kunnen diagnosticeren, zoals long polls of blocking.

Daarom is de taak voor Rust duidelijk. We houden vast aan ons doel: "laag genoeg voor een kernel, hoog genoeg voor een GUI". Sterker nog, ik denk dat de verschuiving naar agents betekent dat we iets meer "ruis" kunnen tolereren in de vorm van expliciete calls naar clone() of share() — maar niet te veel, want het "happy path" van de code moet duidelijk en evident blijven[^8], zelfs als we details naar boven halen die belangrijk zijn in specifieke scenario's.

In combinatie met een profiler ontstaat er een effectieve feedbackloop om code snel te laten draaien: Code → Benchmark → Profile → Analyse door Agent → Voorstel (PR) → Verbetering Code.

Betrouwbaarheid is koning

Hoewel de reputatie van goede prestaties mensen naar Rust trekt, is het gevoel dat programmeren in Rust "gewoon beter werkt" wat hen laat blijven. De basistheorie is dat het typesysteem en de vangrails van Rust agents op het juiste pad houden:

"Rust is een perfecte taal voor agents, aangezien het, als het compileert, ongeveer correct is."
— Greg Brockman (@gdb), 2 juli 2026

Ik denk dat daar een kern van waarheid in zit: talen als Rust, OCaml of Haskell delen dit gevoel van "als het compileert, werkt het", en agents zullen daarvan profiteren.

Testen is niet genoeg, typesystemen helpen

"Testen kan de aanwezigheid van bugs aantonen, maar niet hun afwezigheid."
— Edsger W. Dijkstra, 1970

Het schrijven van tests is nooit genoeg geweest om aan te tonen dat een programma correct is — maar met agents is dat nog minder het geval. Het gebeurt vaak dat mijn eerste paar tests geweldig lijken en de volgende dan volledig in de soep loopt. Meestal op een manier die ik me niet eens kan voorstellen. Wanneer ik dieper graaf, realiseer ik me dat de agent de logica die ik probeerde uit te drukken volledig heeft gemist[^9].

Dit is waar een typesysteem echt schittert — vooral een geavanceerd systeem zoals dat van Rust. Typesystemen bieden vangrails die de agent op koers houden. In Rust gaan die vangrails verder dan simpele zaken als "hebben alle velden de juiste namen" en strekken ze zich uit tot zaken als het nooit hoeven sluiten van een socket.

Typesystemen zijn ook niet genoeg

"Typesystemen kunnen de afwezigheid van bugs aantonen, maar niet de aanwezigheid van correctheid."
— Ik, die faalde om een zin van gelijke welsprekendheid te bedenken[^10], 2026

Typesystemen zijn nuttig, maar ze hebben inherente limieten. Een typesysteem is een eenvoudige set regels die ervoor zorgen dat je (bepaalde soorten) fouten vermijdt. Ze vertellen je echter niet of je het juiste doet — alleen dat je niet (op bepaalde manieren) het verkeerde doet. Als je verder wilt gaan, heb je een bewijssysteem (proof system) nodig: iets waarmee je kunt aantonen dat rijkere eigenschappen actief waar zijn, in plaats van alleen dat je bugs vermijdt.

Er zijn veel interessante bewijstools voor Rust, zoals Verus, Creusot, Aeneas en Kani. Als startpunt kun je bewijzen dat je code panic-free is, wat veel bugs elimineert. Maar je kunt ook verder gaan en beweringen (assertions) toevoegen die aantonen dat je code de resultaten berekent die je verwacht.

Sterke vangrails zorgen voor betere prestaties

Het implementeren van bewijzen is niet alleen goed voor de correctheid, maar ook voor de snelheid. Dat klinkt contra-intuïtief, maar het is waar. Zoals eerder genoemd worden geoptimaliseerde cryptografische algoritmen nu door agents geschreven. Dit is mogelijk omdat deze algoritmen een zeer duidelijke wiskundige definitie hebben. Je kunt de agent in feite zeggen: "doe wat je wilt, zolang je maar kunt bewijzen dat de code nog steeds het correcte resultaat berekent". Deze bewijzen kunnen worden gedaan met theorem provers zoals Lean of Rocq.

Voor Rust is een goed voorbeeld hiervan de omgang met unsafe code. Momenteel zijn mensen soms terughoudend om unsafe code te gebruiken, zelfs als het de code sneller zou maken, omdat het risico op fouten te groot is. Maar wat als je een prover kunt gebruiken om aan te tonen dat je unsafe code in feite veilig is (d.w.z. niet in staat is om undefined behavior te veroorzaken)? Dan ben je vrij om naar hartenlust te optimaliseren.

Hebben we nog typesystemen nodig als we bewijzen gebruiken?

Je zou je kunnen afvragen: als we een bewijssysteem op onze code toepassen, hebben we dan nog wel typesystemen nodig? Het antwoord is absoluut ja. Typesystemen zijn oneindig veel eenvoudiger om mee te werken. Hiermee kun je alle soorten vervelende bugs uitsluiten, zodat je je "bewijsenergie" alleen kunt richten op de echt belangrijke zaken.

Neem als eenvoudig voorbeeld deze Java-code:

void setFoo(Bar bar) {
    this.foo = bar;
    assert this.foo == bar;
}

Zonder meer code is het onmogelijk om te bewijzen of deze assertion waar is, omdat er andere threads kunnen zijn die dit muteren. In tegenstelling hiermee moet de volgende Rust-code waar zijn (zolang de Eq operator reflexief is voor Bar):

fn set_foo(&mut self, bar: Bar) {
    self.foo = bar;
    assert_eq!(self.foo, bar);
}

We weten dit omdat het typesysteem van Rust garandeert dat &mut self een unieke referentie impliceert. Dit is precies hoe Verus werkt: door te vertrouwen op de Rust borrow checker om uniciteit bij te houden, wordt de taak van de SMT-solver vereenvoudigd, waardoor bewijscontrole veel sneller en betrouwbaarder wordt.

De richting van Rust op het gebied van betrouwbaarheid

Mijn visie is dat Rust moet inzetten op: als het compileert, werkt het. Ondanks de expressiviteit van het typesysteem van Rust, zijn er veel zaken die het niet kan vangen. Dit omvat veelvoorkomende zaken, zoals "deze methode leest slechts één specifiek veld", maar ook complexere zaken zoals "geen logging van persoonlijk identificeerbare informatie". We moeten werken aan het wegnemen van die limieten, zodat agents complexere eigenschappen kunnen bewijzen.

We moeten ook de ervaring van het integreren van bewijstools verbeteren door te werken aan een uitbreidbare compiler. Hoewel de bestaande Rust-gebaseerde bewijstools cool zijn, is het gebruik ervan vaak een haperende ervaring met vervelende macro's en vastgepinde compilerversies. We kunnen dit beter.

Een noordster: geen unsafe code meer

Ik wil een "noordster" voor Rust voorstellen: geen unsafe code meer. Hiermee bedoel ik niet dat we het unsafe-trefwoord nooit meer gebruiken. In plaats daarvan bedoel ik dat we de kracht hebben om te bewijzen dat alle unsafe code die we schrijven correct is en geen undefined behavior kan veroorzaken.

Het weten welke code precies gecontroleerd moet worden is al een grote stap voorwaarts, evenals het normaliseren van het idee dat bibliotheken verantwoordelijk zijn voor het beschermen van hun gebruikers via veilige API-grenzen[^11]. Maar gezien het vermogen van agents om kwetsbaarheden te vinden, moeten we onze standaard verhogen als we de constante stroom van CVE's willen stoppen[^12].

Ontwerp is een open probleem

Voordat je dingen gaat bewijzen of optimaliseren, moet je een duidelijk idee hebben van wat je bouwt. Voor zover ik weet, is de huidige stand van zaken in deze ruimte in feite variaties op "markdown-driven-development": documentatie ontwikkelen en hopen dat agents er aandacht aan besteden.

Ik weet niet in hoeverre Rust hier een rol in speelt. Er zijn stappen die we zouden kunnen nemen die nuttig kunnen zijn — bijvoorbeeld manieren om interface van implementatie te scheiden, zodat het gemakkelijker is om de interface geïsoleerd te beoordelen of om te zien wanneer de agent daar wijzigingen heeft aangebracht[^13].

Ook denk ik dat er ruimte is voor specifieke "modellerings-talen", waarmee je snel met agents kunt itereren op high-level ontwerpen en invarianten zonder direct in de details van de code te duiken. In dit kader verwijs ik naar het artikel "Principles of Anchor Engineering" van Kari Wilhelm, die goed beschrijft wat het betekent om de belangrijkste elementen van een ontwerp naar voren te halen en het coderen daarvan aan te sturen.

Conclusie

Wat maakt Rust een goede keuze voor ontwikkeling met agents?

  • Prestaties: Het biedt goede standaardprestaties en kan, in combinatie met een profiler, tot in het detail worden afgestemd.
  • Vangrails: Het typesysteem biedt sterke vangrails. Door agents correct in te stellen, kunnen deze vangrails worden versterkt via technieken zoals new types.

En wat zou het vanuit een taalontwerp-perspectief kunnen verbeteren? De focus verschuift naar een balans waarbij agents het coderen doen en mensen zich meer richten op het begrijpen van de code:

  1. "Als het compileert, werkt het": Ons typesysteem is ons grote voordeel. We moeten het expressiever en functioneler maken zodat agents niet vastlopen bij het proberen eromheen te werken. Daarnaast is het doel om unsafe code mogelijk te maken zonder onveiligheid, door bewijzen te ondersteunen.
  2. "Laag genoeg voor een kernel, hoog genoeg voor een GUI": Zorg dat we de knoppen beschikbaar houden voor prestatie-optimalisatie, terwijl de intentie van de code duidelijk blijft.
  3. Uitbreidbaar en veelzijdig: We moeten de geest van uitbreidbaarheid brengen in de compiler, zodat we meer ontwikkelstijlen kunnen ondersteunen (bijv. GPU, diepe taal-interop) en theorem provers kunnen integreren.

Tot slot verwijs ik naar het artikel "What’s easy now? What’s hard now?" van Marc Brooker. Hij stelt dat hoe duidelijker de succescriteria voor een taak gespecificeerd kunnen worden, hoe gemakkelijker de taak is. Taken die we traditioneel als "moeilijk" beschouwen (bijv. een efficiënte implementatie van een cryptografisch algoritme) worden mogelijk geautomatiseerd, terwijl taken die we als "makkelijk" zagen (bijv. een unieke, overtuigende website maken) waardevoller worden.

Vanuit een programmeertaal-perspectief versterkt dit mijn gevoel dat de grootste innovatie zal komen van ontwerptalen: talen die architectuur en bedoeld gedrag op een zeer hoog niveau vastleggen. Het doel is om mensen intuïtief een ontwerp te laten specificeren dat wordt vertaald naar effectieve vangrails (typesysteem-checks, lints of stellingen). Agents nemen vervolgens de taak op zich om dit ontwerp te vertalen naar code in een traditionele taal zoals Rust, waarbij mensen slechts zelden naar de code zelf kijken. Dit maakt het ontwerp van traditionele talen niet minder interessant, maar het verandert de afwegingen wel fundamenteel.

***

[^1]: Ik ben stiekem altijd jaloers geweest op mensen die codeerden met ponskaarten. Ik wil zo graag "wereldmoe" klinken! Ik ben blij dat ik eindelijk oud genoeg ben om te zeggen: "Ik herinner me dat we CONFIG.SYS moesten bewerken voordat we een computerspel konden spelen!" en dat jongere programmeurs verschrikt reageren. [^2]: Ik herinner me nog dat mijn vader me vertelde dat hij een schijf van 10MB voor me had gekocht, maar stiekem had hij een schijf van 40MB gekocht om me te verrassen. Het leek absurd groot. "Ik heb nooit meer een nieuwe schijf nodig!" [^3]: Mijn god, we gebruiken zelfs weer vi! Mijn eerste editor! [^4]: Ik heb een electron-app gebouwd! En het was zo makkelijk! En het lezen van vreemde papers is veel toegankelijker nu ik een LLM kan vragen om alle wiskundige jargon te vertalen. [^5]: Ik herinner me dat ik Alex Crichton probeerde te vertellen hoe ik shareware bestelde uit een papieren catalogus door een cheque per post te sturen, en hij reageerde: "Ik begrijp geen enkel zelfstandig naamwoord in die zin". Hoogtepunt van mijn leven, vlak na Rust 1.0. En misschien de geboorte van mijn kind en mijn huwelijk. Denk ik. [^6]: Ik zeg niet dat Rust de enige taal is die goed past. Ik heb bijvoorbeeld gehoord dat Go een heel goede match is voor agentisch programmeren; het raakt een ander optimaal punt dat agents helpt om snel te itereren (hoewel ik vermoed dat agents vaker data races en subtiele bugs doorlaten die Rust zou hebben voorkomen). [^7]: Het feit dat agentische ontwikkeling meer ruimte biedt voor "knoppen" is goed voor de prestaties van Rust, maar het is waarschijnlijk een nog betere match voor prestaties in andere talen. Het afstemmen van een GC was traditioneel het werk van een expert, maar agents kunnen die rol tegenwoordig waarschijnlijk goed invullen. [^8]: Over dit punt ben ik nu nog meer overtuigd van het belang van ergonomische RC. Agents zijn goed in het introduceren van de extra clones die nodig zijn voor async tasks, maar de resulterende code is zo irritant om te lezen dat het de kern van de zaak verhult. [^9]: "Claude, dit is niet wat we hebben afgesproken!" — ik, al te vaak. [^10]: Zo dichtbij, toch? Ik kon de landing net niet maken. [^11]: Te vaak beschouwen C++-bibliotheken het als voldoende om gebruikers te vertellen dat ze het "verkeerd vasthouden" — d.w.z. dat de gebruiker verantwoordelijk is voor undefined behavior door misbruik van de API. Rust neemt het standpunt in dat een veilige API zijn gebruikers moet beschermen, ongeacht hoe ze deze misbruiken. [^12]: Om eerlijk te zijn, als Rust een stroom CVE's tegenkomt, dan ervaren andere talen zoals C++ en Java een regelrechte vloed, aangezien zij de bescherming van het typesysteem van Rust missen. [^13]: De wraak van .h bestanden?