Esencją tego bloga jest informowanie o narzędziach programistycznych, jakich można użyć do rozwiązania problemów codziennej pracy. Do tej pory jednak skupiałem się na językach programowania, a przecież kod, który piszemy musi w jakiś sposób powstać. I nie zamierzam tu zaczynać kolejnej wojny o wyższości Vim nad Emacs, Eclipse nad Netbeans, Scite nad Textpad itd. Chciałbym się podzielić swoim (może ciągle niewielkim) doświadczeniem z programowania w Ruby oraz Haskellu.
Bez wielkiego wstępu i rozwodzenia się, uważam że do tworzenia oprogramowania w Ruby najlepszym środowiskiem jest Netbeans 6. Dzięki pracy autorów "Ruby plugin" możemy cieszyć się komfortem pisania z podpowiadaniem składni, dokumentacją API, debuggerem, refaktoryzacją oraz pełną integracją z samym IDE. Na obecną chwilę, Netbeans (w wersji 6.0) nie ma godnej konkurencji.
Opisując Netbeans nieprzypadkowo użyłem określenia "najlepsze środowisko", ponieważ do szybkiego edytowania kodu w Ruby (oraz Haskell) używam jEdit.
Jest to bardzo mocno rozszerzalny i konfigurowalny edytor z podświetlaniem składni, zaawansowanym formatowaniem tekstu i obsługą wielu plików na raz. Jednak dopiero po uzupełnieniu podstawowej funkcjonalność o wtyczki (np. wspaniałą SuperAbbrevs) zamienia się w prawdziwy kombajn. Polecam - wypróbujcie jEdit! A - czy wspomniałem już że jest całkowicie darmowy? :-)
środa, 28 listopada 2007
wtorek, 20 listopada 2007
Różne podejścia do wielowątkowości
Pisałem ostatnio o języku Haskell. Uważam go za jeden z lepszych w dziedzinie programowania wielowątkowego w modelu "tradycyjnym", czyli z współdzieloną pamięcią (dzięki połączeniu czysto języka funkcyjnego i technologii STM - bardzo przystępnie przedstawionej w "Beautiful concurrency"). Nie jest jednak jedyne możliwe podejście do problemu. Oto krótkie zestawienie stosowanych rozwiązań wraz z komentarzem:
- brak jakiejkolwiek obsługi wielowątkowości (Javascript, PHP) - wbrew pozorom to też jest jakieś rozwiązanie, w końcu nie zawsze potrzeba takiej funkcjonalności
- pseudo-wątki obsługiwane przez runtime języka (Python, Ruby) - w językach z pseudo-wątkami (określanymi często w j. angielskim jako "green threads") to środowisko uruchomieniowe języka samo zajmuje się obsługą współbieżności w najprostszej formie, czyli przełączania kontekstu pomiędzy wątkami. Stosując takie rozwiązanie nie da się w pełni wykorzystać potencjału współczesnych procesorów wielordzeniowych czy maszyn wieloprocesorowych
- wątki natywne operujące na współdzielonej pamięci (C, Java, Haskell) - języki te udostępniają interfejs umożliwiający operacje na wątkach sterowanych przez system operacyjny (ang. "native threads"). Rozwiązanie to cechuje z jednej strony możliwość tworzenia bardzo wydajnych aplikacji, ale z drugiej duży stopień trudności związany z zapewnieniem poprawności działania. To tu pojawiają się zagadnienia synchronizacji dostępu, blokad, semaforów itp.
- niezależne, natywne lub kontrolowane przez runtime wątki z systemem komunikatów (Erlang) - według wielu znawców tematu tylko to rozwiązanie ma przyszłość w świecie, w którym -dziesiąt czy -set rdzeni lub procesorów przestaje być fantazją. Atutem jest tu niemal nieograniczona skalowalność takiego podejścia, wadą - konieczność zaadoptowania diametralnie innej koncepcji budowy oprogramowania.
piątek, 9 listopada 2007
Procesory wielordzeniowe a programowanie
Miesiąc temu obiecałem napisać o rewolucji w sposobie myślenia o pisaniu programów. Zdradziłem wtedy, że chodzi o język Haskell. Czym więc jest Haskell? Jest językiem programowania (to raczej nie jest niespodzianka) o następujących cechach:
Całe to zamieszanie z czystością podejścia funkcyjnego raczej odstrasza niż zachęca. Dlaczego więc twórcy Haskella tak się przy tym upierają? Jakie korzyści może to przynieść? I co to wszystko ma wspólnego z tematem posta - procesorami wielordzeniowymi?
Własności funkcji matematycznej - funkcja zawsze da ten sam wynik dla określonego parametru i nigdy nie wpłynie na wywołanie innej funkcji - sprawiają, że jej zastosowanie w programie komputerowym daje potężne możliwości optymalizacji dla kompilatora lub interpretera. Nie ma też żadnego ryzyka związanego z uruchomieniem np. 32 współbieżnych wątków obliczających dowolną funkcję (czego nie można powiedzieć o uruchomieniu chociażby 2 współbieżnych wątków dokonujących modyfikacji w systemie plików). A nie ma lepszej metody na wykorzystanie coraz bardziej popularnych procesorów wielordzeniowych niż aplikacje wielowątkowe.
Chwila - wielu czytelników zapewne teraz zwróci uwagę - aplikacje wielowątkowe to przecież żadna nowość. Zaletą podejścia w Haskellu jest jednak to, że jawnie oddzielone są od siebie bezpieczne bloki kodu (gdzie bezpieczeństwo oznacza "możliwość wpływania na swoje otoczenie") od potencjalnie niebezpiecznych.
- czysto funkcyjny - o ile programowanie funkcyjne jest samo w sobie diametralnie innym podejściem do tworzenia oprogramowania, to dopiero "czysta" funkcyjność Haskella jest prawdziwym unikatem, o którym za chwilę
- funkcje jako wartości podstawowe - funkcje mogą być parametrami lub wartościami wynikowymi innych funkcji
- currying funkcji - w największym skrócie chodzi o to, że podając np. dwuparametrowej funkcji "dodaj" jeden parametr (np. 3), otrzymujemy w rezultacie nową funkcję jednoparametrową (którą można by nazwać "dodaj3do")
- z silną i statyczną kontrolą typów - nie zamierzam bynajmniej rozpoczynać tu dyskusji o wyższości świąt Bożego narodzenia na świętami Wielkiejnocy (w wydaniach "silna czy słaba" / "statyczna czy dynamiczna" kontrola typów), zawsze sugeruję użycie najbardziej odpowiedniego narzędzia w określonej sytuacji
- z odgadywaniem typów - interpreter lub kompilator potrafi (w zdecydowanej większości przypadków) poprawnie "odgadnąć" typ wyrażenia, więc programista nie musi go jawnie deklarować; tak przy okazji, to połączenie statycznej kontroli typów z ich odgadywaniem typów jest bardzo dobrym rozwiązaniem, bo pozwala ograniczyć charakterystyczną dla statycznie typowanych języków "rozwlekłość" kodu
Całe to zamieszanie z czystością podejścia funkcyjnego raczej odstrasza niż zachęca. Dlaczego więc twórcy Haskella tak się przy tym upierają? Jakie korzyści może to przynieść? I co to wszystko ma wspólnego z tematem posta - procesorami wielordzeniowymi?
Własności funkcji matematycznej - funkcja zawsze da ten sam wynik dla określonego parametru i nigdy nie wpłynie na wywołanie innej funkcji - sprawiają, że jej zastosowanie w programie komputerowym daje potężne możliwości optymalizacji dla kompilatora lub interpretera. Nie ma też żadnego ryzyka związanego z uruchomieniem np. 32 współbieżnych wątków obliczających dowolną funkcję (czego nie można powiedzieć o uruchomieniu chociażby 2 współbieżnych wątków dokonujących modyfikacji w systemie plików). A nie ma lepszej metody na wykorzystanie coraz bardziej popularnych procesorów wielordzeniowych niż aplikacje wielowątkowe.
Chwila - wielu czytelników zapewne teraz zwróci uwagę - aplikacje wielowątkowe to przecież żadna nowość. Zaletą podejścia w Haskellu jest jednak to, że jawnie oddzielone są od siebie bezpieczne bloki kodu (gdzie bezpieczeństwo oznacza "możliwość wpływania na swoje otoczenie") od potencjalnie niebezpiecznych.
Subskrybuj:
Posty (Atom)