Intro
Om te beginnen: ik heb nog maar heel weinig in Lua geprogrammeerd. Ik heb dit super simpele spel gemaakt, en ben momenteel bezig met een ander. Het is echter genoeg geweest om me de nadelen van programmeren in Lua te laten inzien.
Klachten
Hier zijn mijn drie voornaamste klachten:
1) Dynamische en (enigszins) zwakke typering
2) Alles is een runtime error
3) Gebrek aan klassen
Voorbeelden
Dynamische Typering/Lack of Type Annotations
Laten we een functie als specifiek voorbeeld nemen.
function Ent:update_state(cmd, params) if cmd == 'at' then self.x, self.y = params.x, params.y endend
Op de eerste plaats wordt het lezen van de functie zelf moeilijk. Wat neemt deze functie in? En wat geeft hij terug, als hij al iets teruggeeft? We krijgen deze informatie niet door naar de functie handtekening te kijken. In plaats daarvan moeten we de body van de functie doorlezen. Voor eenvoudige functies, is dit ok. Maar voor langere en complexere functies wordt het bepalen van het terugkeertype een heel gedoe.
Daarnaast wordt het lezen/schrijven/debuggen van functie-aanroepen moeilijk. We kunnen een waarde van elk type doorgeven aan cmd
! Als we ent:update_state(4, …)
uitvoeren, zal de ent
niet worden bijgewerkt. Maar in plaats van dit op te vangen als een typefout, zullen we het moeten debuggen tijdens runtime.
In het algemeen zijn talen met dynamische typing moeilijker te lezen. Als je het type van een variabele wilt weten, moet je nadenken over het pad van uitvoering van de code, in plaats van een blik te kunnen werpen op een type-annotatie (bijv. Java) of het type te controleren in een REPL (bijv. met behulp van ghci om Haskell-typen te controleren). De taal Hack is een uitzondering. Het is dynamisch getypeerd, maar biedt nog steeds statische type-controle. Met Lua krijg je alle voors en tegens van een dynamisch getypeerde taal. Het is super eenvoudig om code te schrijven, en net zo moeilijk om correctheid te verzekeren.
Runtime/Silent Errors
function test_func(test_arg) print(test_arg)endtest_func() -- prints 'nil'
Hier is een scenario dat ik vaak ben tegengekomen. Ik moet een functie toevoegen/verwijderen/wijzigen. Dus ik verander de functie, en dan ga ik rond en verander alle aanroepen. Dit is niet zo erg; ik kan het hele project doorzoeken en de aanroepen één voor één bijwerken. Maar wat als ik er een mis? Of wat als ik een nieuwe aanroep toevoeg en vergeet dat ik de functie veranderd heb? Je raadt het al: een runtime failure!
Random ander voorbeeld: 4 / 0 = inf
. Het geeft geen foutmelding.
Geen Klassen
Er is dit, dat goed werkt. Maar het mist nog steeds een heleboel OO functies: methode zichtbaarheid en interfaces om er een paar te noemen. Zonder de eerste, wordt het heel gemakkelijk om de toestand van een object te veranderen van overal in de code, en veel moeilijker om te redeneren over de toestand van objecten.
Het is niet allemaal slecht
Ok, dat zijn alle voorbeelden die ik heb (voor nu). Ik heb eigenlijk een behoorlijk stuk geleerd terwijl ik dit schreef. Ik wilde gaan klagen over global scoping, maar vond dit. Ik wilde gaan klagen over type coercion, maar dat valt wel mee (het gebeurt alleen met strings en ints). En het blijkt dat er een getypte versie van Lua is! Ik heb het nog niet geprobeerd, maar het ziet er veelbelovend uit. Als je dit leest en je hebt typedlua geprobeerd, laat me weten hoe het is in de commentaren.
Waarom klaag ik?
Ik realiseer me dat klagen over al deze dingen misschien een beetje dom lijkt. Lua is een lichtgewicht scripting taal; de dingen die ik hierboven noemde zijn niet altijd nadelen. Lua is niet ontworpen voor het bouwen van grote, complexe applicaties. Maar dat is waarom ik dit post in de Love2D subreddit. Het lijkt erop dat mensen een aantal vrij grote en complexe spellen maken met Lua en Love2D. Bijvoorbeeld, Mari0, Warlock’s Tower, etc. Hoe doen zij (jij?) het? Ik kan me niet echt voorstellen dat ik een “echt” spel kan maken in Lua/Love2D. Als ik een week pauze zou nemen, zou ik waarschijnlijk de helft van de code vergeten, en veel te veel tijd verspillen aan het uitzoeken van de types van al mijn variabelen en functies. Gebruiken spellen meestal Lua als een “lijm” taal, en implementeren ze de rest in C/C++? Is het maken van een groot spel gemakkelijker in Lua dan in andere talen, zelfs met de problemen die ik hierboven vermeldde? Waarom gebruiken mensen Lua voor grote spellen, als ze dat al doen?
Bedankt dat je de tijd hebt genomen om dit te lezen :D. En als ik hierboven iets fout heb gedaan, laat het me weten!
Interessante dingen om te lezen:
Lua: Goede, slechte en lelijke delen
zwakke en sterke types