Stackless Python jest cokolwiek egzotycznym jezykiem skryptowym.
Jego zalozenia wydawaly sie dawno temu ojcom projektu fajne i ladne.
Python jest fajny, ladny, modny, dorodny i nowoczesny. Jest jednak jezykiem skryptowym. Wszystkie cywilizowane jezyki skryptowe wspolczesnie sa (moga byc) prekompilowane przynajmniej do binarnego betakodu (analogicznie do Javy) ale skryptowosc niesie ze soba obciazenia optymalizacyjne jakich nie maja jezyki projektowane z gory jako kompilowane (jak C).
Np musza przechowywac hashtable z nazwami zmiennych, bo zawsze w jezyku skryptowym moze sie uwidziec programiscie odwolac sie do zmeinnej po nazwie ze stringa. Architektura prekompilowanego skrypta musi tez byc gotowa na to ze nagle ktos wykona kawalek kodu w postaci tekstu. Taki C nie ma tych obciazen, Java jest w polowie drogi, a Python je ma (chyba ze sie wogole calkowicie myle co do pythona i gadam nie na temat, co jest mozliwe bo ogladalem go lata temu). So - skryptowy -> wolniejszy.
Stackless to uroczy pomysl zeby nie bylo stosu. Nie ma stosu, nie ma wywolywania funkcji w funkcji. To wymusza pewien styl pisania podobny do np AJAXa;
W normalnym jezyku mozesz miec (jezyk jest podobny do Javy ale nie jest zadnym prawdziwym jezykiem jesli wejdziesz w szczegoly);
class Laser extends Dzialo {
...
strzelaj(cel) {
obrazenia = this.obrazenia * cel.getResisty(this);
cel.zadajObrazenia(obrazenia);
getStatek().getLocalSystem().sendEvent(new PokazywanieKolorowejKreseczki(this, cel));
}
obslugaEventaPilotNacisnalSpust() {
this.strzelaj(getStatek().getAktualnieWybranyCel()));
}
...
}
W stackless nie masz stosu, nie ma stosu nie ma wywolania innej funkcji, wiec juz linijka;
obrazenia = this.obrazenia * cel.getResisty(this);
nie jest mozliwa bo nie mozesz odwolac sie do funkcji (metody) cel.getResisty(*). Jesli chcesz oprogramowac strzelanie laserem musisz postepowac mniej wiecej tak;
class Laser extends Dzialo {
...
obslugaEventaPilotNacisnalSpust() {
sendEvent(new ZadawanieObrazen(getStatek.getAktualnieWybranyCel, this.obrazenia));
sendEvent(getStatek.getLocalSystem, new PokazywanieKolorowejKreseczki(getStatek, getStatek.getAktualnieWybranyCel));
}
...
}
class Statek {
obslugaEventaZadawanieObrazen(jakich) {
hapeki = hapeki - jakich*this.MojeResisty;
}
}
Czyli - nie masz jednej funkcji (metody) ktora obsluguje calosc zdazenia, wylicza sobie wszystko dociagajac dane z innych metod, tylko zglaszasz zdarzenia do kolejki i listenery to po kolei chwytaja. Dlatego mozliwe jest np ze juz skonczyles strzelac z lasera ale z powodu laga obrazenia pojawia sie u celu dopiero po paru sekundach. Wszelkie zlozone procesy to nie rozbudowane odnogi funkcji obslugi guzika tylko serie wzajemnie wywolujacych sie zdarzen ktora bedzie sie toczyc nawet jesli gosciowi ktory wcisnal guzik dawno padl klient i proces go obslugujacy.
Jest to w jakims stopniu logiczne i uzasadnione dla gry sieciowej, ale nie jest bardzo intuicyjne dla przecietnego programisty. Dlatego miedzy innymi byly zawsze takie proste misje - ciezko bylo zwerbowac duzo ludzi byli wystarczajaco bystrzy zeby skryptowac misje w stackles pythonie i jednoczesnie chcieli robic misje (a nie nalezec do glownego dev team) ... no i jeszcze przeniesc sie do Islandii.
Do tego Stackless Python niesie ze soba ograniczenia architektoniczne ktore bardzo utrudniaja rozwoj i optymalizacje czegokolwiek zaczynajac od pewnej skali.
Gdyby wszystko od poczatku bylow C++, problemy bylyby inne, ale tak ogolniej wielka optymalizacja calosci bylaby prawdodpobnie bardziej realna (chociaz wszystko zalezy od poczatkowych zalozen architelktury jeszcze bardziej niz od jezyka - o tych jednak nie wiadomo za duzo poza sercem CCP).