GoSuda

Vergelijking van taalontwerp in LLM-gebaseerde codegeneratieomgevingen: abstractiekosten en de explicietheid van Go

By Rabbit Princess views ...

Moderne talen

Moderne talen verwijzen naar talen die, in vergelijking met eerdere talen, een hogere productiviteit, stabiliteit, beveiliging en onderhoudbaarheid bieden. Deze talen integreren actief de nieuwste technieken en concepten en bieden ontwikkelaars efficiëntere en veiligere ontwikkelinstrumenten. Representatieve moderne talen zijn onder andere Java, Rust, Python en TypeScript, die de volgende kenmerken hebben.

1. Objectgeoriënteerd ontwerp ( OOP )

Moderne talen zijn grotendeels ontworpen op basis van objectgeoriënteerde concepten. Objectgeoriënteerd programmeren ondersteunt principes zoals encapsulatie, overerving en polymorfisme, en maakt de structuur van een programma helder en flexibel door complexe systemen op te delen in kleinere objecten die afzonderlijk worden beheerd. Dit is vooral doeltreffend bij grootschalige softwareontwikkeling, waarbij het de ontwikkelkosten en -inspanning beheersbaar houdt en de problemen die bij onderhoud kunnen ontstaan vermindert.

2. Syntactische suiker en expressies

Moderne talen bieden diverse syntactische suiker en op expressies gebaseerde syntaxis om de leesbaarheid van code en de ontwikkelproductiviteit te verhogen. Functies zoals de ternaire operator, lambda-expressies en patroonherkenning verminderen boilerplate-code, maken code voorspelbaar en verhogen de productiviteit van ontwikkelaars.

3. Modulesysteem

Moderne talen maken het via een modulesysteem mogelijk een programma op te splitsen in meerdere eenheden die afzonderlijk beheerd kunnen worden. Dit bevordert het hergebruik van code en het beheer van afhankelijkheden, en maakt onderhoud eenvoudiger naarmate een project groeit. Representatieve voorbeelden zijn Maven/Gradle voor Java, Cargo voor Rust en npm/yarn voor TypeScript.

4. Tussentaal en virtuele machines

Moderne talen maken gebruik van tussentalen en virtuele machines om platformonafhankelijkheid, prestatie-optimalisatie en beveiliging te realiseren. Representatieve voorbeelden zijn JVM, LLVM, WASM en GraalVM.

Ontwikkeling in het AI-tijdperk en de beperkingen van moderne talen

Moderne talen zijn ontstaan op basis van de veronderstelling dat mensen het merendeel van de code schrijven. Vanzelfsprekend is het doel van moderne talen het verminderen van repetitief werk, het verhogen van de productiviteit en het effectief realiseren van grootschalige software via structuren die samenwerking tussen ontwikkelaars mogelijk maken. Toch begint deze veronderstelling in het AI-tijdperk steeds meer te wankelen. AI-gebaseerde hulpmiddelen zoals Copilot en Cody automatiseren een groot deel van het schrijven van code, en de hoeveelheid code die één ontwikkelaar kan produceren neemt sterk toe. Hierdoor verandert het kenmerk van moderne talen dat vroeger als voordeel werd ervaren geleidelijk in een verouderd nadeel.

Objectgeoriënteerd ontwerp

AI kan een structuur waarin alle informatie binnen één functie of module is gespecificeerd snel en nauwkeurig analyseren. Naarmate de context toeneemt, neemt echter het aantal af te leiden segmenten toe, waardoor de productiviteit en nauwkeurigheid van AI afnemen. Code die volgens OOP is opgebouwd, verdeelt de logica over meerdere objecten in plaats van deze op één plek te beheren, wat er uiteindelijk toe leidt dat AI meer context nodig heeft. Bekijk de onderstaande code.

 1public class AnimalHandler {
 2    public void handle(Animal animal) {
 3        animal.speak();
 4    }
 5}
 6
 7public class Main {
 8    public static void main(String[] args) {
 9        AnimalHandler handler = new AnimalHandler();
10
11        Animal a1 = new Dog();
12        Animal a2 = new Cat();
13        Animal a3 = new Horse();
14
15        handler.handle(a1);
16        handler.handle(a2);
17        handler.handle(a3);
18    }
19}

In de bovenstaande code moet AI om te bepalen welke werkelijke handeling de methode speak() uitvoert, de volgende redeneerstappen herhalen:

  1. Van welke concrete klasse is animal de instantie?
  2. Waar is de in die klasse overschreven methode speak() gedefinieerd?
  3. Waar staan de definities van de klassen Dog en Cat, en wat is het gedrag binnen die klassen?
  4. Is er een mogelijkheid dat de klassen Dog en Cat in andere klassen worden overschreven?

Deze informatie is niet verzameld in één bestand of één functie, maar moet worden gevolgd via de relaties tussen klassenbestanden en de overervingsstructuur. Bovendien zijn elementen die tijdens runtime worden bepaald, zoals reflectie of dynamisch laden, voor AI vergelijkbaar met een black box, waardoor analyse in feite onmogelijk is.

Syntactische suiker en expressies

AI geeft de voorkeur aan expliciet gedrag boven impliciet gedrag, en combineert liever eenvoudige structuren tot één juist antwoord dan complexe structuren te gebruiken. Syntactische suiker daarentegen staat diverse vormen van expressie toe, terwijl het onderliggende gedrag vaak gelijk of vergelijkbaar is. AI moet de betekenis van deze diverse expressies afzonderlijk leren en kan het moeilijk worden te bepalen welke syntaxis in een specifieke situatie het beste aanbevolen kan worden.

Tussentaal en virtuele machines

AI wordt grotendeels getraind op broncode. Tussentaal (bytecode) daarentegen verliest tijdens het compileren betekenisvolle informatie zoals variabelenamen, en moet tijdens de uitvoering door de virtuele machine opnieuw worden geïnterpreteerd. Dit maakt het voor AI zeer moeilijk om te begrijpen of te transformeren. Zo is het voor AI mogelijk om TypeScript naar Go te vertalen, maar is het vrijwel onmogelijk om V8-engine-bytecode om te zetten naar JVM-bytecode of machinecode.

De werkelijk moderne taal voor het AI-tijdperk

Uit bovenstaande blijkt dat de kenmerken van moderne talen in feite verouderde elementen zijn die niet geschikt zijn voor het AI-tijdperk. Welke taal kan dan de meest geschikte moderne taal voor het AI-tijdperk worden? Hierbij kunnen we inspiratie putten uit de elementen die eerdere moderne talen juist hebben afgewezen. Een moderne taal voor het AI-tijdperk

  1. moet een expliciete syntaxis en een natuurlijke stroom hebben.
  2. moet afstand doen van overmatige OOP-structuren en een vlakke, eenvoudige structuur hebben.
  3. realiseert meerdere functies met een beperkt aantal basissleutelwoorden, in plaats van onnodige syntactische suiker of impliciete patronen.
  4. moet een eenvoudig en voorspelbaar buildsysteem hebben in plaats van een complex buildsysteem.

De taal die het best aansluit bij deze criteria is Golang. Go is ontworpen om met een minimaal aantal kernsleutelwoorden en een eenvoudige combinatie van syntaxis de meeste praktische functies te kunnen implementeren, en sluit overtollige abstractie en impliciet gedrag consequent uit. Dit is een structuur die zowel voor ontwikkelaars als voor AI gunstig is bij het interpreteren en genereren van code.

De eigenschappen van Go, die gericht zijn op een voorspelbare en vlakke structuur, expliciete stroom en consistente syntaxis, passen beter bij een ontwikkelomgeving waarin AI actief meewerkt dan de bestaande moderne talen die zijn ontworpen met mensen als uitgangspunt. Het conservatieve ontwerpprincipe van Go, dat ooit als verouderd werd beschouwd, blijkt in het AI-tijdperk juist de meest vooruitstrevende keuze te zijn.