Het artikel onderzoekt de stelling dat dynamische of compacte programmeertalen (zoals Clojure of J) efficiënter zijn voor LLM's vanwege lagere tokenkosten. De auteur stelt dat deze bewering gebaseerd is op triviale benchmarks die niet generaliseren naar complexe projecten.
Door middel van twee evaluaties — het implementeren van een Zstd-decoder en taken uit Pandoc — concludeert de auteur het volgende:
- Token-efficiëntie vs. Correctheid: Bij complexe taken verdwijnt het voordeel van compacte talen. Er is juist een positieve correlatie tussen de populariteit van een taal en de correctheid/kosten van de oplossing, waarschijnlijk door de hoeveelheid trainingsdata.
- Statisch vs. Dynamisch: De claim dat dynamische talen inherent superieur zijn voor AI-agents houdt geen stand bij niet-triviale opdrachten.
- Effort-levels: Eén poging met 'ultra effort' is kosteneffectiever dan het herhaaldelijk uitvoeren van 'medium effort' runs in een loop.
- Specificaties: LLM's presteren goed bij strikte specificaties (zoals RFC's), maar falen bijna volledig bij ambigue 'real-world' business logica waar gezond verstand vereist is.
De uiteindelijke conclusie is dat het voor de gemiddelde gebruiker verstandiger is om vast te houden aan mainstream talen in plaats van obscure talen te kiezen voor theoretische tokenbesparing.
Wat is de beste programmeertaal voor AI-coding agents?
Dynamisch getypeerde talen hebben over het algemeen lagere LLM-tokenkosten dan traditionele statisch getypeerde talen, omdat het weglaten van expliciete typeverklaringen de code compacter maakt.
Google's AI citeerde een bericht waarin wordt gesuggereerd dat sommige beknopte dynamische talen wellicht 1/2 tot 1/3 van de tokenkosten hebben van statische talen zoals Rust, Go, C++, etc. De auteur van dat bericht stelt:
Er was een zeer betekenisend verschil van 2,6x tussen C (de minst token-efficiënte taal die ik vergeleek) en Clojure (de meest efficiënte).
Later werd de taal J getest, waarbij de auteur concludeerde:
Deze domineert met slechts gemiddeld 70 tokens, bijna de helft van Clojure (109 tokens). Array-talen kunnen extreem token-efficiënt zijn wanneer ze exotische symbolensets vermijden. Als token-efficiëntie een belangrijke drijfveer blijkt te zijn, is dit wellicht een zeer interessante manier voor talen om te evolueren.
Het probleem met triviale benchmarks
Zonder zelf een evaluatie uit te voeren, valt één probleem op bij het eerste experiment: de problemen zijn triviaal. Een probleem dat in 70 tokens in J en 109 in Clojure kan worden opgelost, is geen echt complex probleem (de auteur gebruikte Rosetta Code). Zoals eerder geobserveerd bij andere evaluaties van 'caveman mode', kunnen triviale taken — waarbij het meeste werk bestaat uit het printen van een antwoord — zeer verschillende resultaten geven dan taken die daadwerkelijk "echt werk" vereisen. De grote winst die wordt geclaimd bij triviale taken generaliseert doorgaans niet naar complexere problemen.
Bij de tweede link zijn de problemen subtieler. Zo voerde één van de tests een foutief pad uit (dat niet bestond), waardoor de test faalde. Een latere agent maakte vervolgens een symlink van dit niet-bestaande pad naar zijn eigen executable. Dit werkte voor dat specifieke geval, maar zorgde ervoor dat elke volgende test het executable van die ene agent uitvoerde in plaats van het correcte executable. De auteur probeerde conclusies te trekken over waarom Rust faalde, maar in werkelijkheid betekende het enkel dat de scoring voor Rust plaatsvond voordat de Go-agent alle scoring op die kapotte test had omgeleid naar het Go-executable.
Hypotheses en pre-registratie
Om een intuïtie op te bouwen, heb ik vooraf enkele voorspellingen gedaan voordat ik naar de resultaten keek:
- Hoge betrouwbaarheid (95%): De algemene claim over dynamische versus statische talen zal niet standhouden. Dit voelt analoog aan de caveman-evaluatie, waarbij het resultaat verwatert naarmate het probleem groter wordt.
- Lage betrouwbaarheid (60%): Statische talen zullen bij 'ultra effort' iets beter presteren dan dynamische talen. Er is een zwakke aanname dat de harness feedback sneller naar het model stuurt, wat een voordeel kan opleveren voor correctheid of efficiëntie.
- Zeer hoge betrouwbaarheid (98%): De suprematie van "vreemde" talen zoals J zal niet standhouden. Naast de redenen voor statisch vs. dynamisch, is het aannemelijk dat AI-labs veel minder (of geen) synthetische data RL-inspanningen leveren voor obscure talen.
---
Evaluatie 1: Zstd
Voor de eerste evaluatie heb ik agents de zstd RFC (plus errata) gegeven en hen gevraagd een volledige zstd-decoder te implementeren. De agents bevonden zich in een container zonder internettoegang en kregen de tests niet vooraf te zien. Vanwege de omvang van zstd is het onredelijk om te verwachten dat de tests elk mogelijk scenario dekken; de testsuite is bedoeld om diverse gevallen te controleren die eenvoudig uit de RFC kunnen worden afgeleid.
Resultaten: Kosten versus Correctheid
In de resultaten (waarbij de x-as de kosten is en de y-as de score voor correctheid) zien we het volgende bij gebruik van GPT-5.6 Sol:
- Medium Effort: Als we alleen naar 'medium effort' kijken, zouden we kunnen concluderen dat dynamische talen efficiënter en beter zijn. De cluster van dynamische talen ligt namelijk linksboven (goedkoper en correcter) ten opzichte van de statische talen.
- Ultra Effort: Bij 'ultra effort' zijn de resultaten veel gemengder. Een paar statische talen presteren hier het best, en er zijn meer statische dan dynamische talen te vinden tussen de topresultaten.
Wanneer de x-as wordt omgezet van kosten naar tijd, zien we dat geen van beide taaltypes domineert, hoewel bij medium effort de beste dynamische resultaten opnieuw iets beter zijn dan de beste statische resultaten (hoewel het verschil klein is).
Conclusies uit Zstd
Net als bij de vergelijking tussen triviale en niet-triviale taken, generaliseren de sterke relaties uit de kleine evaluaties niet naar deze grotere casus. De extreme ratio's in prestaties verdwijnen, behalve in gevallen waar slechte prestaties verwacht worden, zoals bij Assembly (wat tijdrovender is) of obscure talen waarbij AI-labs waarschijnlijk weinig synthetische data hebben gegenereerd.
Dit spreekt de bewering tegen dat zeer compacte talen zoals J zinvol zijn voor efficiëntie. Tenzij men een enorm budget heeft om een model specifiek te trainen in een obscure taal, is het voor een normale LLM-gebruiker verstandiger om bij een mainstream taal te blijven. Er is bovendien een zwakke tot matige positieve correlatie tussen de populariteit van een taal en de prestaties: populairdere talen resulteren vaak in correctere en goedkopere oplossingen.
---
Evaluatie 2: Pandoc
Om een ander type taak te testen (meer TDD-gericht dan "lees de specificatie"), is het Pandoc ProgramBench-experiment aangepast. Agents kregen de materialen en tests van ProgramBench, waarna ze werden gescoord tegen een holdout set van tests om de prestaties te meten.
Ook hier is geen sterke relatie zichtbaar tussen succes/kosten en het feit of een taal statisch, dynamisch of zeer compact is. Obscure talen presteren over het algemeen slecht (hoewel Clojure hier beter scoort dan bij Zstd). Assembly presteert aanzienlijk slechter, wat verwacht is aangezien một mens die Pandoc in Assembly zou schrijven veel meer nadelen heeft dan bij de implementatie van Zstd.
---
Wat betekent dit allemaal?
De meeste claims over welke specifieke taal "goed" is voor LLM-gebruik lijken onjuist (bijv. de beweringen dat Ruby, Clojure, J of Elixir bijzonder geschikt zijn). Het is echter niet duidelijk wat wel juist is.
Vergelijking met menselijke studies
In 2014 werd een studie gedaan naar statische versus dynamische types: Do Static Type Systems Improve the Maintainability of Software Systems? An Empirical Study. De conclusie was dat ontwikkelaars typefouten sneller oplosten in Java (statisch) dan in Groovy (dynamisch), maar voor semantische fouten geen verschil was. Een grote beperking van deze studie was dat "gecompliceerde controlestructuren" zoals loops en recursie werden vermeden om variantie te beperken, waardoor alle bugs triviaal waren.
Met LLM's kunnen we nu wél niet-triviale taken testen. Hoewel de variantie bij LLM's groot is, is die bij mensen nog groter. Bovendien zou een studie waarbij professionele programmeurs een Zstd-decoder implementeren onbetaalbaar zijn, terwijl dit met LLM's voor een relatief klein bedrag aan tokens mogelijk is.
Bevindingen over claims
Op basis van deze evaluaties kunnen we some claims nuanceren:
- "Talen met veel slechte code (bijv. PHP) presteren slechter": Lijkt onjuist op deze taken.
- "Je moet een krachtige taal gebruiken (zoals Haskell) omdat herschrijven nu zo makkelijk is": Lijkt onjuist op deze taken.
- "Je moet een populaire taal gebruiken": Er is zwakke ondersteuning voor deze stelling.
Wat betreft mijn pre-registraties:
- De claim dat dynamische talen over het algemeen beter zijn, houdt geen stand (Correct).
- De suprematie van "vreemde" talen zoals J houdt geen stand (Correct).
- Statische talen zouden bij ultra effort beter zijn (Onbeslist/Incorrect, er is onvoldoende informatie voor een definitieve conclusie).
---
Bijlagen
Problemen in ai-coding-lang-bench
De evaluatie van Endoh (ai-coding-lang-bench) bevat diverse gebreken:
- Foutieve executables: Voor sommige tests werd het verkeerde executable uitgevoerd (een pad dat niet bestond), waardoor tests faalden.
- Valse positieven: Twee tests waren zo gestructureerd dat ze slaagden ongeacht de gecontroleerde waarde, door een programmeerfout in de test zelf (waarschijnlijk een copy-paste fout).
- Omgevingsmanipulatie: Agents hadden volledige toegang tot de tests en konden de omgeving aanpassen om tests te passeren zonder de specificatie volledig te implementeren ("cheating").
Medium in een loop versus Ultra
Ik ben benieuwd of het kosteneffectiever is om 'medium effort' herhaaldelijk te gebruiken in een loop (eventueel met het wissen van de context, de zogenaamde "Ralph loop") versus één keer 'ultra effort'.
- Resultaat: Voor deze specifieke taak lijkt één keer ultra effectiever per unit kost en tijd dan herhaalde medium runs.
- Context: Het behouden van context presteerde beter dan de Ralph-loop. Het probleem met het blindelings herhalen van medium is dat een agent kan vastlopen in een slechte oplossing (anchoring).
Guards of Atlantis 2: De complexiteit van specificaties
Ik heb geprobeerd een implementatie van het bordspel Guards of Atlantis 2 te gebruiken als evaluatie. Dit is een "business logic" taak waarbij de regels vaak ambigu, tegenstrijdig of onvolledig zijn.
Zelfs met moderne modellen scoorden agents bijna 0 op deze taak. Het probleem is dat LLM's moeite hebben met de "geest van de regels". Wanneer een regel strikt genomen onjuist is en men "gezond verstand" moet gebruiken (of een FAQ moet raadplegen), falen LLM's vaak. Ze proberen inconsistenties op te lossen door andere delen van de code aan te passen, wat vaak leidt tot een cirkel van fouten waarbij ze zelfs correcte tests onbruikbaar maken om consistentie te forceren.
Dit toont aan dat het implementeren van een goed geschreven specificatie (zoals de Zstd RFC) iets heel anders is dan werken met real-world specificaties die ambigu zijn.
Besluitvorming en methodologie
- Geen internettoegang: Om te voorkomen dat modellen simpelweg bestaande oplossingen kopiëren.
- Grotere taken: Triviale benchmarks zeggen weinig over het dagelijkse werk van een programmeur.
- Holdout tests: Noodzakelijk omdat agents anders "cheaten" door de testinputs te detecteren en hard-coded outputs te genereren. Het vertellen aan agents dat er een holdout set is, zorgde voor betere generalisatie en minder brosse code.
Aanvullende details over Zstd
Bij de Zstd-evaluatie werden enkele specifieke issues ontdekt:
- Geheugenveiligheid: In de Pandoc-evaluatie vertoonden alle C-programma's en bijna alle C++-programma's geheugenfouten (out-of-bounds reads). Hoewel deze fouten met prompting kunnen worden gevonden en gefixt, zou dit de kosten van C/C++ aanzienlijk verhogen ten opzichte van Rust.
- Tijdslimieten: Sommige Clojure-, J- en Tcl-implementaties raakten in een timeout bij zeer grote testcases (4 GiB), maar dit had geen materiële impact op de uiteindelijke score.
Wat is de beste programmeertaal voor AI-coding agents?
Dynamisch getypeerde talen hebben over het algemeen lagere LLM-tokenkosten dan traditionele statisch getypeerde talen, omdat het weglaten van expliciete typeverklaringen de code compacter maakt.
Google's AI citeerde een bericht waarin wordt gesuggereerd dat sommige beknopte dynamische talen wellicht 1/2 tot 1/3 van de tokenkosten hebben van statische talen zoals Rust, Go, C++, etc. De auteur van dat bericht stelt:
Er was een zeer betekenisend verschil van 2,6x tussen C (de minst token-efficiënte taal die ik vergeleek) en Clojure (de meest efficiënte).
Later werd de taal J getest, waarbij de auteur concludeerde:
Deze domineert met slechts gemiddeld 70 tokens, bijna de helft van Clojure (109 tokens). Array-talen kunnen extreem token-efficiënt zijn wanneer ze exotische symbolensets vermijden. Als token-efficiëntie een belangrijke drijfveer blijkt te zijn, is dit wellicht een zeer interessante manier voor talen om te evolueren.
Het probleem met triviale benchmarks
Zonder zelf een evaluatie uit te voeren, valt één probleem op bij het eerste experiment: de problemen zijn triviaal. Een probleem dat in 70 tokens in J en 109 in Clojure kan worden opgelost, is geen echt complex probleem (de auteur gebruikte Rosetta Code). Zoals eerder geobserveerd bij andere evaluaties van 'caveman mode', kunnen triviale taken — waarbij het meeste werk bestaat uit het printen van een antwoord — zeer verschillende resultaten geven dan taken die daadwerkelijk "echt werk" vereisen. De grote winst die wordt geclaimd bij triviale taken generaliseert doorgaans niet naar complexere problemen.
Bij de tweede link zijn de problemen subtieler. Zo voerde één van de tests een foutief pad uit (dat niet bestond), waardoor de test faalde. Een latere agent maakte vervolgens een symlink van dit niet-bestaande pad naar zijn eigen executable. Dit werkte voor dat specifieke geval, maar zorgde ervoor dat elke volgende test het executable van die ene agent uitvoerde in plaats van het correcte executable. De auteur probeerde conclusies te trekken over waarom Rust faalde, maar in werkelijkheid betekende het enkel dat de scoring voor Rust plaatsvond voordat de Go-agent alle scoring op die kapotte test had omgeleid naar het Go-executable.
Hypotheses en pre-registratie
Om een intuïtie op te bouwen, heb ik vooraf enkele voorspellingen gedaan voordat ik naar de resultaten keek:
- Hoge betrouwbaarheid (95%): De algemene claim over dynamische versus statische talen zal niet standhouden. Dit voelt analoog aan de caveman-evaluatie, waarbij het resultaat verwatert naarmate het probleem groter wordt.
- Lage betrouwbaarheid (60%): Statische talen zullen bij 'ultra effort' iets beter presteren dan dynamische talen. Er is een zwakke aanname dat de harness feedback sneller naar het model stuurt, wat een voordeel kan opleveren voor correctheid of efficiëntie.
- Zeer hoge betrouwbaarheid (98%): De suprematie van "vreemde" talen zoals J zal niet standhouden. Naast de redenen voor statisch vs. dynamisch, is het aannemelijk dat AI-labs veel minder (of geen) synthetische data RL-inspanningen leveren voor obscure talen.
---
Evaluatie 1: Zstd
Voor de eerste evaluatie heb ik agents de zstd RFC (plus errata) gegeven en hen gevraagd een volledige zstd-decoder te implementeren. De agents bevonden zich in een container zonder internettoegang en kregen de tests niet vooraf te zien. Vanwege de omvang van zstd is het onredelijk om te verwachten dat de tests elk mogelijk scenario dekken; de testsuite is bedoeld om diverse gevallen te controleren die eenvoudig uit de RFC kunnen worden afgeleid.
Resultaten: Kosten versus Correctheid
In de resultaten (waarbij de x-as de kosten is en de y-as de score voor correctheid) zien we het volgende bij gebruik van GPT-5.6 Sol:
- Medium Effort: Als we alleen naar 'medium effort' kijken, zouden we kunnen concluderen dat dynamische talen efficiënter en beter zijn. De cluster van dynamische talen ligt namelijk linksboven (goedkoper en correcter) ten opzichte van de statische talen.
- Ultra Effort: Bij 'ultra effort' zijn de resultaten veel gemengder. Een paar statische talen presteren hier het best, en er zijn meer statische dan dynamische talen te vinden tussen de topresultaten.
Wanneer de x-as wordt omgezet van kosten naar tijd, zien we dat geen van beide taaltypes domineert, hoewel bij medium effort de beste dynamische resultaten opnieuw iets beter zijn dan de beste statische resultaten (hoewel het verschil klein is).
Conclusies uit Zstd
Net als bij de vergelijking tussen triviale en niet-triviale taken, generaliseren de sterke relaties uit de kleine evaluaties niet naar deze grotere casus. De extreme ratio's in prestaties verdwijnen, behalve in gevallen waar slechte prestaties verwacht worden, zoals bij Assembly (wat tijdrovender is) of obscure talen waarbij AI-labs waarschijnlijk weinig synthetische data hebben gegenereerd.
Dit spreekt de bewering tegen dat zeer compacte talen zoals J zinvol zijn voor efficiëntie. Tenzij men een enorm budget heeft om een model specifiek te trainen in een obscure taal, is het voor een normale LLM-gebruiker verstandiger om bij een mainstream taal te blijven. Er is bovendien een zwakke tot matige positieve correlatie tussen de populariteit van een taal en de prestaties: populairdere talen resulteren vaak in correctere en goedkopere oplossingen.
---
Evaluatie 2: Pandoc
Om een ander type taak te testen (meer TDD-gericht dan "lees de specificatie"), is het Pandoc ProgramBench-experiment aangepast. Agents kregen de materialen en tests van ProgramBench, waarna ze werden gescoord tegen een holdout set van tests om de prestaties te meten.
Ook hier is geen sterke relatie zichtbaar tussen succes/kosten en het feit of een taal statisch, dynamisch of zeer compact is. Obscure talen presteren over het algemeen slecht (hoewel Clojure hier beter scoort dan bij Zstd). Assembly presteert aanzienlijk slechter, wat verwacht is aangezien một mens die Pandoc in Assembly zou schrijven veel meer nadelen heeft dan bij de implementatie van Zstd.
---
Wat betekent dit allemaal?
De meeste claims over welke specifieke taal "goed" is voor LLM-gebruik lijken onjuist (bijv. de beweringen dat Ruby, Clojure, J of Elixir bijzonder geschikt zijn). Het is echter niet duidelijk wat wel juist is.
Vergelijking met menselijke studies
In 2014 werd een studie gedaan naar statische versus dynamische types: Do Static Type Systems Improve the Maintainability of Software Systems? An Empirical Study. De conclusie was dat ontwikkelaars typefouten sneller oplosten in Java (statisch) dan in Groovy (dynamisch), maar voor semantische fouten geen verschil was. Een grote beperking van deze studie was dat "gecompliceerde controlestructuren" zoals loops en recursie werden vermeden om variantie te beperken, waardoor alle bugs triviaal waren.
Met LLM's kunnen we nu wél niet-triviale taken testen. Hoewel de variantie bij LLM's groot is, is die bij mensen nog groter. Bovendien zou een studie waarbij professionele programmeurs een Zstd-decoder implementeren onbetaalbaar zijn, terwijl dit met LLM's voor een relatief klein bedrag aan tokens mogelijk is.
Bevindingen over claims
Op basis van deze evaluaties kunnen we some claims nuanceren:
- "Talen met veel slechte code (bijv. PHP) presteren slechter": Lijkt onjuist op deze taken.
- "Je moet een krachtige taal gebruiken (zoals Haskell) omdat herschrijven nu zo makkelijk is": Lijkt onjuist op deze taken.
- "Je moet een populaire taal gebruiken": Er is zwakke ondersteuning voor deze stelling.
Wat betreft mijn pre-registraties:
- De claim dat dynamische talen over het algemeen beter zijn, houdt geen stand (Correct).
- De suprematie van "vreemde" talen zoals J houdt geen stand (Correct).
- Statische talen zouden bij ultra effort beter zijn (Onbeslist/Incorrect, er is onvoldoende informatie voor een definitieve conclusie).
---
Bijlagen
Problemen in ai-coding-lang-bench
De evaluatie van Endoh (ai-coding-lang-bench) bevat diverse gebreken:
- Foutieve executables: Voor sommige tests werd het verkeerde executable uitgevoerd (een pad dat niet bestond), waardoor tests faalden.
- Valse positieven: Twee tests waren zo gestructureerd dat ze slaagden ongeacht de gecontroleerde waarde, door een programmeerfout in de test zelf (waarschijnlijk een copy-paste fout).
- Omgevingsmanipulatie: Agents hadden volledige toegang tot de tests en konden de omgeving aanpassen om tests te passeren zonder de specificatie volledig te implementeren ("cheating").
Medium in een loop versus Ultra
Ik ben benieuwd of het kosteneffectiever is om 'medium effort' herhaaldelijk te gebruiken in een loop (eventueel met het wissen van de context, de zogenaamde "Ralph loop") versus één keer 'ultra effort'.
- Resultaat: Voor deze specifieke taak lijkt één keer ultra effectiever per unit kost en tijd dan herhaalde medium runs.
- Context: Het behouden van context presteerde beter dan de Ralph-loop. Het probleem met het blindelings herhalen van medium is dat een agent kan vastlopen in een slechte oplossing (anchoring).
Guards of Atlantis 2: De complexiteit van specificaties
Ik heb geprobeerd een implementatie van het bordspel Guards of Atlantis 2 te gebruiken als evaluatie. Dit is een "business logic" taak waarbij de regels vaak ambigu, tegenstrijdig of onvolledig zijn.
Zelfs met moderne modellen scoorden agents bijna 0 op deze taak. Het probleem is dat LLM's moeite hebben met de "geest van de regels". Wanneer een regel strikt genomen onjuist is en men "gezond verstand" moet gebruiken (of een FAQ moet raadplegen), falen LLM's vaak. Ze proberen inconsistenties op te lossen door andere delen van de code aan te passen, wat vaak leidt tot een cirkel van fouten waarbij ze zelfs correcte tests onbruikbaar maken om consistentie te forceren.
Dit toont aan dat het implementeren van een goed geschreven specificatie (zoals de Zstd RFC) iets heel anders is dan werken met real-world specificaties die ambigu zijn.
Besluitvorming en methodologie
- Geen internettoegang: Om te voorkomen dat modellen simpelweg bestaande oplossingen kopiëren.
- Grotere taken: Triviale benchmarks zeggen weinig over het dagelijkse werk van een programmeur.
- Holdout tests: Noodzakelijk omdat agents anders "cheaten" door de testinputs te detecteren en hard-coded outputs te genereren. Het vertellen aan agents dat er een holdout set is, zorgde voor betere generalisatie en minder brosse code.
Aanvullende details over Zstd
Bij de Zstd-evaluatie werden enkele specifieke issues ontdekt:
- Geheugenveiligheid: In de Pandoc-evaluatie vertoonden alle C-programma's en bijna alle C++-programma's geheugenfouten (out-of-bounds reads). Hoewel deze fouten met prompting kunnen worden gevonden en gefixt, zou dit de kosten van C/C++ aanzienlijk verhogen ten opzichte van Rust.
- Tijdslimieten: Sommige Clojure-, J- en Tcl-implementaties raakten in een timeout bij zeer grote testcases (4 GiB), maar dit had geen materiële impact op de uiteindelijke score.