Nyelvtervezési összehasonlítás LLM-alapú kódgenerálási környezetben: az absztrakció költsége és a Go explicitsége

Modern nyelvek
A modern nyelvek olyan nyelveket jelentenek, amelyek a korábbi nyelvekhez képest nagyobb termelékenységet, stabilitást, biztonságot és karbantarthatóságot biztosítanak. Ezek a nyelvek aktívan alkalmazzák a legújabb technikákat és koncepciókat, és hatékonyabb, biztonságosabb fejlesztőeszközöket nyújtanak a fejlesztők számára. Jellemző modern nyelvek közé tartozik a Java, a Rust, a Python és a TypeScript, amelyek a következő jellemzőkkel rendelkeznek.
1. Objektumorientált tervezés ( OOP )
A modern nyelvek többsége objektumorientált koncepciókra épül. Az objektumorientáltság támogatja az olyan elveket, mint az egységbe zárás (encapsulation), az öröklődés és a polimorfizmus, és a komplex rendszereket kisebb egységekre, objektumokra bontva kezeli, ami a programok szerkezetét világossá és rugalmassá teszi. Ez különösen hatékony nagy méretű szoftverfejlesztés során a fejlesztési költségek és ráfordítások szabályozásában, valamint a karbantartás során felmerülő problémák csökkentésében.
2. Szintaktikai cukor és kifejezésalapú szintaxis
A modern nyelvek a kód olvashatóságának és a fejlesztési termelékenységnek a növelése érdekében számos szintaktikai cukrot és kifejezésalapú szintaxist kínálnak. A ternáris operátor, a lambda-kifejezések és a mintaillesztés (pattern matching) ilyen funkciói csökkentik a sablonkód (boilerplate) mennyiségét, előre jelezhetővé teszik a kódot, és javítják a fejlesztők termelékenységét.
3. Modulrendszer
A modern nyelvek modulrendszeren keresztül teszik lehetővé a program több egységre bontását és kezelését. Ez megkönnyíti a kód újrafelhasználhatóságát és a függőségek kezelését, valamint a projekt méretének növekedése esetén is egyszerűvé teszi a karbantartást. Jellemző példák erre a Java Maven/Gradle, a Rust Cargo és a TypeScript npm/yarn rendszere.
4. Köztes nyelvek és virtuális gépek
A modern nyelvek platformfüggetlenség, teljesítményoptimalizálás és biztonság érdekében köztes nyelveket és virtuális gépeket alkalmaznak. Jellemző példák erre a JVM, az LLVM, a WASM és a GraalVM.
Fejlesztés az AI korszakában és a modern nyelvek korlátai
A modern nyelvek abból a feltevésből születtek, hogy a kód nagy részét emberek írják. Természetesen a modern nyelvek célja a ismétlődő munka csökkentése, a termelékenység növelése, valamint az a struktúra, amely lehetővé teszi a fejlesztők együttműködését és a nagy méretű szoftverek hatékony megvalósítását. Az AI korszakban azonban ez a feltevés fokozatosan megdől. Az olyan AI-alapú eszközök, mint a Copilot vagy a Cody, a kódírás nagy részét automatizálják, és egyetlen fejlesztő által előállítható kód mennyisége robbanásszerűen nő. Ennek következtében a modern nyelvek korábban előnyösnek érzett jellemzői fokozatosan elavult hátrányokká válnak.
Objektumorientált tervezés
Az AI könnyen és pontosan elemzi azokat a struktúrákat, amelyekben egy függvényen vagy modulon belül minden információ explicit módon szerepel. Ezzel szemben minél nagyobb a kontextus, annál több a következtetendő szakasz, ezért az AI termelékenysége és pontossága csökken. Az OOP alapú kód a logikát nem egy helyen kezeli, hanem több objektum között szétosztja, ami végeredményben több kontextust tesz szükségessé az AI számára. Nézzük az alábbi kódot.
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}
A fenti kódban az AI-nak, hogy megértse, valójában mit csinál a speak() metódus, ismételten a következő következtetéseket kell levonnia:
- Az animal melyik konkrét osztály példánya?
- Az adott osztályban felülírt speak() metódus hol van definiálva?
- A Dog és a Cat osztályok definíciói hol találhatók, és mi a működésük belsőleg?
- Nincs-e lehetőség arra, hogy a Dog és a Cat osztályokat más osztályok felülírják?
Ezek az információk nincsenek egy fájlban vagy egy függvényben összegyűjtve, hanem az osztályfájlok közötti kapcsolatok és az öröklődési szerkezet követésével érthetők meg. Ráadásul a futásidőben eldőlő elemek, mint a reflexió vagy a dinamikus betöltés, az AI szemszögéből fekete dobozhoz hasonlítanak, így gyakorlatilag elemezhetetlenek.
Szintaktikai cukor és kifejezésalapú szintaxis
Az AI a implicit működés helyett az explicit működést részesíti előnyben, és a komplex szerkezetek használata helyett inkább az egyszerű struktúrák kombinálásával hoz létre egyetlen helyes megoldást. Ezzel szemben a szintaktikai cukor sokféle kifejezést tesz lehetővé úgy, hogy belső működésük gyakran azonos vagy hasonló. Az AI-nak ezeknek a különböző kifejezéseknek a jelentését egyesével kell megtanulnia, és nehézzé válhat annak eldöntése, hogy adott helyzetben melyik szintaxist érdemes javasolnia.
Köztes nyelv és virtuális gép
Az AI többnyire forráskód alapján tanul. Ezzel szemben a köztes nyelv (bytecode) fordítási folyamat során elveszíti a változónevekhez hasonló jelentéstartalmakat, és futtatáskor a virtuális gépnek kell újraértelmeznie. Ez az AI számára rendkívül nehezen megérthető vagy átalakítható feladat. Például az AI számára a TypeScriptből Go nyelvre történő átalakítás lehetséges, ugyanakkor a V8 engine bytecode-jának JVM bytecode-ra vagy gépi kódra történő átalakítása gyakorlatilag lehetetlen.
Az AI korszak igazi modern nyelve
A fentiekből kiderül, hogy a modern nyelvek jellemzői valójában az AI korszakban nem alkalmasak, elavult elemek. Melyik nyelv lehet tehát az AI korszak legmegfelelőbb modern nyelve? Ennek megválaszolásában támpontot adhatnak azok az elemek, amelyeket a korábbi modern nyelvek elutasítottak. Az AI korszak modern nyelvének
- explicit szintaxissal és természetes folyamatszerkezettel kell rendelkeznie;
- a túlzott OOP struktúrát elhagyva síkszerű és egyszerű szerkezettel kell rendelkeznie;
- a szükségtelen szintaktikai cukor és implicit minták helyett korlátozott számú alapkulcsszóval kell több funkciót megvalósítania;
- összetett build rendszer helyett egyszerű és előre jelezhető build rendszerrel kell rendelkeznie.
Ezeknek a szempontoknak a legjobban a Golang felel meg. A Go nyelvet úgy tervezték, hogy a legkevesebb alapvető kulcsszóval és egyszerű szintaktikai kombinációkkal is a gyakorlatban hasznos funkciók nagy részét megvalósíthassuk, és következetesen kizárja a szükségtelen absztrakciókat és az implicit működést. Ez nemcsak a fejlesztők számára, hanem az AI számára is előnyös szerkezet a kód értelmezése és generálása során.
A kiszámítható és síkszerű struktúra, az explicit folyamatok és a következetes szintaxis felé törekvő Go jellemzői az emberi fejlesztőkre tervezett hagyományos modern nyelvekkel szemben jobban illeszkednek az olyan fejlesztési környezetekhez, ahol az AI aktívan részt vesz a munkában. A Go egykor elavultnak tartott konzervatív tervezési filozófiája így az AI korszakban éppen a legelőrehaladottabb választássá válik.