niedziela, 19 października 2008

Python – pierwsze starcie

"Języki typowane dynamiczne - wolność w popełnianiu błędów"


Jestem znany z przywiązania do języków typowanych statycznie, jednak żeby się nie ograniczać postanowiłem poszukać czegoś dla siebie wśród języków z typowaniem dynamicznym*. Ostatecznie przekonało mnie do tego nowe podejście firmy Microsoft, która postanowiła zainwestować trochę kasy w integrację języków dynamicznych z platformą .NET. O innych względach przemawiających za językami dynamicznymi pisałem już w „Czy języki dynamiczne wyprą języki typowane statycznie?” (http://nandrew.blogspot.com/2007/10/czy-jzyki-dynamiczne-wypr-jzyki.html).


* - pozwolę sobie tutaj zauważyć, że język dynamiczny != język z typowaniem dynamicznym. Nie każdy zdaje sobie z tego sprawę ;)


Wbrew pozorom wybór języka okazał się dość prosty. Postawiłem przed nim niezbyt wygórowane wymagania:

a) normalna, czytelna składnia;

b) duża społeczność (eliminacja niszowych rozwiązań);

c) duża ilość stabilnych bibliotek (żadnych nowości);

d) opinia o języku;


Takie sito wyeliminowało: D (b,c), Groovy (b, c, d), Lisp (a), Perl (a), PHP (a, d), Ruby (a, c), Tcl (a, d).

And the winner is: Python.


Zaraz przejdę do subiektywnego opisu wad i zalet tego języka, najpierw jednak mała dygresja. Pamiętam jak X lat temu Java zdobywała popularność. Jednym z częstszych argumentów wysuwanych przeciw niej była szybkość programów pisanych w tym języku. Zresztą, to był także jeden z powodów, dla których pozostałem przy C++. Teraz jednak, gdy języki dynamiczne zdobywają popularność nagle okazuje się, że nikomu ta szybkość nie jest potrzebna. A przecież taki PHP czy Ruby jest wolniejszy od Javy o rząd wielkości. Jest wiele opinii o przyczynie tego stanu rzeczy, jednak na razie nie będę o tym pisał...


Zalety języka Python

a) ciekawe, czytelna i szybka składnia; bardzo duża społeczność użytkowników; bardzo dużo dojrzałych bibliotek i framework'ów; bardzo dobra opinia o języku (to tyle jeżeli chodzi o „sito”).

b) szybkość w porównaniu do PHP, Ruby, Groovy (Python jest częściowo kompilowany do bytecodu);

c) sporo typów wbudowanych i bardzo duże możliwości manipulowania nimi;

d) IronPython – czyli port języka na platformę .NET. Bardzo duży plus, ponieważ... to nie wymaga nawet uzasadnienia :)


Wady

Trochę tego uzbierałem w trakcie nauki języka.

a) Brak stałych

Bardzo dziwna sytuacja, gdy można bez problemu nadpisać wartość PI (math.pi = 4)! Coś takiego może rozłożyć program na łopatki, a szukanie takiego bug'a to horror, bo kto by pomyślał, że któryś z zaimportowanych modułów nadpisał PI (czyt. jakąś wartość uznawaną za stałą).

Na upartego można opakować stałe w metody typu getXXX(), jednak jest to jawne spowalnianie programu oraz burzenie przyzwyczajeń programistycznych.


b) Niezbyt czytelne elementy składni

Jak już pisałem, składnia Pythona powszechnie jest uważana za „ładną”, jednak zawiera parę elementów, które ją psują:

- prywatne pola klasy oznaczane przez „__” (double underscore) – no jakby jedna twarda spacja nie wystarczyła...;

- parametr self w metodach klas – w większości języków jest on ukryty, co ZMNIEJSZA konieczność bezsensownego klepania w klawiaturę. Tu jednak go postawili na piedestale, po co, dlaczego?! Nie wiem. Gruba przesada.

- tworzenie obiektów ma składnię taką samą jak wywołanie metody – przez co na pierwszy rzut oka nie widać o co chodzi. Dziwne, że pożałowali „self”, a „new” było dla twórców języka zbyt explicit :-\ Brak konsekwencji...


c) Wolny

Nie mówię o szybkości działania odziedziczonej ze „skryptowości” języka, lecz o tym, że przez wbudowane konstrukcje bardzo ułatwione jest wykorzystywanie operacji „czaso i zasobo chłonnych”. Bardzo częste jest wykorzystanie tupli (tworzonych w dużych ilościach), operacji na listach typy zip(), itp. Nawet kompilacja do exe nie pomoże przy nieoptymalnym kodzie. Oczywiście mając na uwadze wydajność przy programowaniu można temu zaradzić.


d) Słaby private

Jak już pisałem składniki prywatne oznacza się jako „__”. Jednak jest to bardzo słaba ochrona i rzeczywiste odwołanie się do takich pół nie stanowi większego problemu (ale lepsze to niż nic).


e) Brak modyfikatora typu protected dla metod

Zastosowanie tego modyfikatora przy skomplikowanych modelach obiektowych jest bardzo częste. Aż dziwne, że zabrakło go w Pythonie (w sumie może nie jest to aż tak dziwne, skoro ledwo private zaimplementowano).


f) Brak klas i metod abstrakcyjnych

Jest to kolejna wada i to dość duża odnosząca się do sposobu implementacji programowania obiektowego. Pod znakiem zapytania staje możliwość zastosowania niektórych wzorców projektowych. Szybkie przeszukiwanie google dało podpowiedź jak zaimplementować klasy abstrakcyjne, jednak wymaga to pisania około 100 linii kodu...

Ergo: ten język chyba nie służy do tworzenia skomplikowanych modeli obiektowych (biorąc pod uwagę punkty d, e, f);


g) Brak bloku try/except/finally

Jest to dziwne, ponieważ są konstrukcje try/except oraz try/finally, jednak try/except/finally jest niedozwolone. Trochę ogranicza to programistę.
Od wersji 2.5 blok try/except/finally jest zaimplementowany. Ach te 3 letnie książki... ("Beginning Python - From Novice to Professional", cyt. "Note that you cannot have both except clauses and a finally clause in the same try statement").


h) Brak porządnego IDE

Dobre środowisko jest nieodzowne przy profesjonalnych zastosowaniach (wspomaganie debuggingu, refactoringu (!), tworzenie GUI graficznie (a nie tekstowo) itp.). Zdaje się, że Python takiego nie posiada. Wprawdzie jest PyDev, jednak wiele mu brakuje do ideału (czyt. Visual Studio), np. IntelliSense działa tylko częściowo (bo zmienne nie maja typów, ale jest to raczej spowodowane cechą języka).

ALE jeżeli weźmiemy pod uwagę IronPython to sytuacja się trochę polepsza, bo VS będzie go wspomagał w przyszłości tak jak każdy inny standardowy język na platformę .NET.


i) Mała popularność wśród firm hostingowych

Język ten ciągle nie jest tak popularny jak PHP jako platforma dla aplikacji web. Przez to trudniej znaleźć hosting komercyjny, o darmowym nie wspominając (nie ma nic sensownego, gdzie by można pobawić się z językiem).

W prawdzie jest darmowy „Google App Engine”, jednak narzuca on wiele ograniczeń i udziwnień, które powodują, że aplikacje nie są przenośne – żaden inny hosting tego nie obsługuje.


Summary

Ze wszystkich języków dynamicznych najlepszy dla mnie okazał się Python. Ma on parę zalet i sporo unikalnych wad. Dopiero próba czasu (czyt. jakiś porządny projekt testowy) pokaże czy da się go użyć w sensownej aplikacji biznesowej (czyli w obszarze moich zainteresowań).


Testowy projekt oparty będzie na Django (czyt. dzengo). Framework webowy wybierałem o wiele dłużej niż język. Jednak tego wyboru nawet nie będę się starał uzasadniać...

10 komentarzy:

Anonimowy pisze...

Skąd wiesz, ze Python jest najlepszy, skoro nic w nim nie zrobiles, a sam wypisales tyle glupich wad zwiazanych z chocby obiektowka?

Takie PHP (od 5.3) obiektowke ma bardzo porzadna, a skladnie ma jak najbardziej normalna. Rozszerzenia tez sa stabilne.. Wydaje sie, ze to jednak bylaby lepsza opcja, jesli chodzi o standardowa obiektowke - jesli chodzi o wydajnosc to Python raczej lepszy.

nandrew pisze...

Pytanie skąd wiem jest trochę dziwne, bo skoro wypisałem sporo wad, to znaczy że mam rozeznanie. Nie napisałem nic poważnego w nim, to fakt - dlatego też podkreśliłem, ze muszę go sprawdzić w poważniejszym projekcie.

Co do PHP i porządnej "obiektówki" - to chyba żart, prawda? Nawet osoby programujące w PHP mi się do tego przyznawały ;) Problem PHP polega na tym, że tam wszystko jest dodawane "na siłę", jest niejednolity, itd. No, ale o wadach PHP to dużo jest na necie, więc nie będę się rozpisywał.

A co do składni, słowo "normalne" jest subiektywne, ale porównanie (Za PSPSolutions :P ):

<?PHP
for($i=1;$i <=5;$i++)
{
  print $i.'
  ';
}
?>

z:

for i in range(1,6):
  print i


daje najlepszy obraz. W dodatku te $ przez zmiennymi... zaciemniają kod! Dla _mnie_ źródła programu w PHP wyglądają jak jeden wielki bałagan - a najgorsze jest to, że czasem muszę w tym grzebać. No, ale to jest moja własna subiektywna opinia i mam do niej prawo ;)

Unknown pisze...

Odniose sie ;)

"Co do PHP i porządnej "obiektówki" - to chyba żart, prawda?"

Nie, jak na jezyki skryptowe, to ma porzadna ;) Chociaz bledy tez ma, ale jesli ktos zna sie na obiektowce, to na pewno sobie lepiej poradzi niz w np. AS. oza tym pisze o PHP5.3 - w fazie dev.

"Problem PHP polega na tym, że tam wszystko jest dodawane "na siłę""

Akurat w PHP5 specjalnie przeprojektowano obiektowke - nie widze "dodawania na sile" - jest zrobione jak powinno byc. Rownie dobrze mozna by napisac, ze do C++ obiektowka zostala wrzucoan na sile ;) (a tak przeciez bylo).

"jest niejednolity,"

Nie rozumiem do konca. Fakt, ze nazewnictwo klas moze byc w caly swiat, ale niejednolitosc OOP w PHP? Jak dla mnie to calkiem jest jednolite.

"No, ale o wadach PHP to dużo jest na necie, więc nie będę się rozpisywał."

Ja bym tam nie przesadzal z wadami, bo glownie wynikaja one nie z samego jezyka, ale z przyzwyczajen/nawykow/kultury programistycznej - niestety prostota jezyka wabi tanich "developerow", ktorzy sprowadzaja na PHP zla opinie.

"A co do składni, słowo "normalne" jest subiektywne"

Piszesz, jakby skladnia byla jakos szczegolnie rozna od skladni np. Javy - akurat te przebija w kwestii obslugi tablic asocjacyjnych/map, a reszta jest de facto wzorowana na C++ - bez szalenstw, ale dobra.

"
for($i=1;$i <=5;$i++)
{
print $i.'
';
}

z:

for i in range(1,6):
print i"

1. W PHP tez mozesz sobie napisac krocej ;)

for($i=1;$i<5;$i++) echo $i;

2. Takie "fajowe", krotkie Pythonowe konstrukcje wydaja mi sie byc... trudne do odczytywania jednak. Oczywiscie nie chodzi o same petle, ale tak bez klamr mozna sie pogubic :P

"daje najlepszy obraz"

No nie daje, bo niesprawiedliwie to napisales :P

"W dodatku te $ przez zmiennymi... zaciemniają kod!"

Czemu? Widac od razu co zmienna, a co nie? I gdy masz kolorowanie skladni, to nie ma wiekszego znaczenia...

"Dla _mnie_ źródła programu w PHP wyglądają jak jeden wielki bałagan"

Zalezy jak napisany. Wiem, ze mozna to schrzanic na maxa i wtedy jest tragedia, ale mozna napisac tez poprawnie - jak juz pisalem wyzej, niestety duzo jest smieciowego kodu - ze wzgledu na prostote jezyka i tanich wykonawcow.

----

ActionScript to dopiero smiec ;) Szlag mnie trafia - Flex Builder nie ma refactoringu, nie ma dobrego kompilartora, sam nie clean'uje projektu, nie ma debuggera.......

nandrew pisze...

1) "[p]oza tym pisze o PHP5.3 - w fazie dev."
No sorry, ale ja nie jestem programistą PHP i trudno mi odnosić się
do czegoś czego co nie ujrzało jeszcze światła dziennego.
Mówię o PHP 4, czyli najpopularniejszym potworku. I dobrze wiem, co mówię
jak pisząc "najpopularniejszy", bo mało co który programista PHP,
którego znam, zna obiektową wersję, a co dopiero poprawki z PHP5!

2) "do C++ obiektowka zostala wrzucoan na sile"
W pełni się zgadzam, dlatego porzuciłem to to na rzecz C#.

3) "(...) wadami, bo glownie wynikaja one nie z samego jezyka, ale z przyzwyczajen/nawykow/kultury programistycznej"
Tak, to jest dobrze znany fakt w środowisku.
Jednak mi, jako osobie, która czasem współpracuje z programistami PHP, trudno
jest zorientować się, co jest winą języka/frameworka, a co umiejętnościami
programisty. Jak większość programistów przedstawia ten sam poziom, to już nie moja wina.
Jeżeli ktoś wybiera język bo jest "łatwy" no to dziękuję bardzo...

4) Składnia - fakt, rzecz subiektywna.
Ale co do dolarków... jak sam zauważyłeś, po co oznaczać zmienne
skoro jest podświetlanie składni?

Unknown pisze...

"1) "[p]oza tym pisze o PHP5.3 - w fazie dev."
No sorry, ale ja nie jestem programistą PHP i trudno mi odnosić się
do czegoś czego co nie ujrzało jeszcze światła dziennego.
Mówię o PHP 4, czyli najpopularniejszym potworku. I dobrze wiem, co mówię
jak pisząc "najpopularniejszy", bo mało co który programista PHP,
którego znam, zna obiektową wersję, a co dopiero poprawki z PHP5!"

PHP5 to standard.

"2) "do C++ obiektowka zostala wrzucoan na sile"
W pełni się zgadzam, dlatego porzuciłem to to na rzecz C#."

Przekrecasz moje mysli. Pelne zdanie: " Rownie dobrze mozna by napisac, ze do C++ obiektowka zostala wrzucoan na sile ;) (a tak przeciez bylo)." - C++ nie byl projektowany pod OOP, ale obiektowka dobrze sie w nim odnalazla (na ile mogla).

"4) Składnia - fakt, rzecz subiektywna.
Ale co do dolarków... jak sam zauważyłeś, po co oznaczać zmienne
skoro jest podświetlanie składni?" - parserowi tak jest wygodniej, w jezyku skryptowym, gdzie nie musisz deklarowac zmiennych, a mozesz nazwy zmiennych ustalac dynamicznie.

$x = 'a';
${$x} = 5; // pod $a jest 5

Poza tym podswietlania skladni wszedzie nie ma i moze nie zadzialac dobrze w przypadku, gdy nie musimy zmiennych deklarowac.

---

PHP5.3 i PHP6 chyba nie ida jednak w dobrym kierunku - choc moze sie myle. I mam taka nadzieje, chociaz przerzucam sie calkowicie na Jave (i hope).

nandrew pisze...

Możliwe, że PHP5 to standard. Tym bardziej dziwi mnie fakt, że znam jeszcze programistów PHP, który albo nie znają "obiektówki" albo dopiero się jej uczą...

Co do C++... on BYŁ projektowany pod OOP. To było główne założenie tego języka (nowa wersja C z obiektami). JEDNAK miejscami tak to niestety wygląda, jakby na siłę naciągali te OOP (co dziwi, bo język w sumie projektowano od podstaw).

Podobnie było w PHP, gdzie niektóre elementy ("dolarki", jak sam zauważyłeś) zrobiono pod wygodę parsera, a nie człowieka. Jednak parser można dostosować do prawie wszystkiego, z człowiekiem gorzej. Aczkolwiek niech będzie, że te "$" to rzecz gustu.
Skoro tylu osobom on nie przeszkadza...

Unknown pisze...

Do wad Pythona możesz dorzucić jeszcze jedną: nie przeznaczony do tworzenia aplikacji biznesowych :) Ponieważ takowe powinny żyć przez jakieś 10-15 lat w ciągu których są nieustannie modyfikowane dbanie o jakość i czytelność kodu jest tutaj najwyższym priorytetem. Weźmy jeszcze pod uwagą, że kod będzie tworzony prze różne zespoły, często pod presją deadline'u, także przez ludzi zmęczonych lub z "don't care attitude". Tworzenie takiego softu w językach skryptowych wymaga bardzo dużej dyscypliny oraz osiągnięcia "by convention" tego co w językach silnie typowanych mamy "by design".
Jednakże będąc fanem Pythona nie mogę nie wspomnieć o bardzo istotnym zastosowaniu w dziedzinie aplikacji enterprise: tworzeniu prototypów (doskonałe narzędzie dla analityka, polecam!).
Poza tym zostawmy języki skryptowe do skryptowania (Blender + Python rulez :)

Anonimowy pisze...

PHP jest złe? Eghm! To python przebija wszystko...

a=0;
a += ++2**3;
print a;

wynik: 8 :E

Przemek pisze...

Możecie powiedzieć coś więcej na temat Phytona? Jestem tutaj nowy i jeszcze nie bardzo rozumiem o czym piszecie. Pozdrawiam :)

nandrew pisze...

@Przemek - co tu więcej pisać, o Pythonie masz dużo informacji w Internecie. I polecam książkę "Fluent Python"