Współczesny świat IT wytworzył co najmniej kilkadziesiąt języków programowania. Każdy z nich ma swoje wady i zalety. Jeśli masz przed sobą jakieś zadanie do wykonania – który z nich powinieneś wybrać?

Krótka odpowiedź na powyższe pytanie brzmi: to zależy, gdyż w zależności od rodzaju zadania zupełnie inny język będzie optymalny. W tym artykule postaram się opisać najważniejsze typy języków programowania, ich zalety i wady oraz rodzaje aplikacji, do których powinny być wykorzystane.

Wysoki czy niski poziom?

Użytecznym rozróżnieniem będzie dla nas to, czy dany język jest językiem wysokiego, czy niskiego poziomu. Języki niskiego poziomu to takie, w których programując odwołujemy się do sposobu działania konkretnego sprzętu, na którym program będzie pracować. Im wyższy poziom języka, tym bardziej język staje się abstrakcyjny (a więc można go np. używać na różnych procesorach) i tym więcej funkcji jest automatyzowanych przez sam język (np. zarządzanie pamięcią). Niestety wyższa abstrakcja i automatyzacja zadań mają swój koszt. Największym problemem jest duży narzut na warstwy pośredniczące między wykonywanym kodem a sprzętem. W przypadku języków skryptowych narzut ten powoduje najczęściej spowolnienie pisanej aplikacji około 100 razy w stosunku do podobnej, ale napisanej w niskopoziomowym języku. Ktoś mógłby w tym momencie pomyśleć, że języki wysokiego poziomu w ogóle nie mają sensu. Nic bardziej mylnego – ich zastosowania pozwala bardzo przyspieszyć proces pisania oprogramowania, a często czas programisty jest dużo bardziej cenny niż nawet najlepszy sprzęt. Dlatego świat systematycznie zmierza w kierunku języków wyższego poziomu.

Gdy decydujemy się na napisanie jakiejś aplikacji, najczęściej stajemy przed wyborem: czy wybrać język niższego poziomu i wolno i żmudnie pisać coś działającego bardzo szybko, czy też bardzo szybko napisać aplikację, która będzie wolno działać. W różnych kontekstach programistycznych sprawdzają się różne rozwiązania. Np. strony internetowe najczęściej tworzy się w językach skryptowych, a więc w językach najwyższego poziomu. Natomiast urządzenia wbudowane (które produkuje się w milionach egzemplarzy) zazwyczaj programowane są w niskopoziomowym języku C, dzięki czemu możliwe jest używane tańszych procesorów i obniżenie kosztów.

Assembler

Assembler to klasa języków programowania najniższego z możliwych poziomów. Cechą charakterystyczną tych języków jest to, że każdy procesor posiada swój własny zestaw komend i dlatego niemożliwym jest uruchomienie aplikacji napisanej dla jednego procesora na drugim procesorze.

Assembler jest obecnie bardzo rzadko używany, stosuje się go głównie do programowania mikrokontrolerów oraz budowania kompilatorów. Jego organizacja sprawia, że nie nadaje się do tworzenia żadnych większych aplikacji, gdyż nad dużą ilością kodu assemblerowego nie sposób zapanować.

C

C jest najpopularniejszym obecnie językiem proceduralnym, a więc takim, którego składnia opiera się na procedurach i strukturach danych. Wadą C jest niepełna przenośność między procesorami. Co prawa kod napisany na jeden procesor skompiluje się także na drugim i obie wersje można będzie uruchomić, ale w praktyce występują różnice w działaniu C na różnych platformach. Np. zmienna całkowita (int) ma różne rozmiary w różnych procesorach. Podobnym problemem jest kolejność bajtów (ang. little/big endian) – różne rodzaje procesorów różnie organizują pamięć operacyjną i często prowadzi to do działania kodu na jednej platformie, a powoduje błędy na drugiej.

Obecnie język C jest wykorzystywany przede wszystkim do pisania aplikacji wbudowanych oraz systemów operacyjnych.

C++

Język C++ jest starszym kuzynem C, a dokładniej jego rozszerzeniem. Język C++ wypiera systematycznie C ze względu na możliwość programowania obiektowego, która doskonale upraszcza tworzenie aplikacji, w tym bardzo dużych projektów. Jednocześnie obiektowość języka nie wprowadziła dużego narzutu. Jeśli na Twoją platformę programistyczną dostępny jest kompilator języka C++, to prawdopodobnie powinieneś wybrać go zamiast C.

Języki C i C++ są właściwie jedynymi językami, w których można tworzyć aplikacje czasu rzeczywistego, np. służące do transmisji dźwięku typu Skype. Przez długi okres C++ był także wykorzystywany do pisania aplikacji desktopowych (biurowych) i obecnie – z powodu bezwładności rynku i konieczności utrzymywania już stworzonych aplikacji – także jest wykorzystywany w tym celu. Kolejny obszar zastosowań to gry komputerowe, gdzie C++ od wielu lat wiedzie zdecydowany prym.

Java/C#

Języki Java i C# to pierwsza generacja języków, które są w 100% oddzielone od typu procesora, na którym pracują. Dzięki temu każda aplikacja napisana w Javie powinna teoretycznie zadziałać w dowolnym systemie operacyjnym i na dowolnym procesorze. Praktyka pokazuje czasem, że Java i C# nie są aż tak dobre, jak to by się wydawało i czasem pojawiają się jakieś problemy z kompatybilnością, ale są one raczej rzadkością.

Java i C# wprowadziły jeszcze jeden bardzo wany mechanizm, który rozwiązał odwieczny problem programistyczny – wycieki pamięci. Programista języka C czy C++ musi pamiętać, żeby zwolnić używaną pamięć, gdy nie będzie już potrzebna. Języki Java i C# same wykrywają, że dana komórka pamięci nie będzie już używana i same zajmują się jej zwolnieniem, dzięki czemu eliminują setki błędów i odciążają programistów. Wadą sprzątania pamięci jest nieprzewidywalność czasowa tego procesu, która sprawia, że Java i C# nie nadają się już do pisania aplikacji czasu rzeczywistego.

Języki Java i C# są najczęściej wykorzystywane do pisania aplikacji biurowych (np. Word) oraz do tworzenia webowych aplikacji biznesowych. Istnieją badania, które pokazują, że napisanie aplikacji w języku Java zajmuje zaledwie 50% czasu potrzebnego do zrobienia tego samego w języku C++. Niestety aplikacja będzie działać wolniej 1,4 do 5 razy.

Języki skryptowe

Ostatni rodzaj języków programowania to języki skryptowe, zwane także językami dynamicznymi (formalnie nie jest to to samo, ale najczęściej języki skryptowe są także językami dynamicznymi). Języki te charakteryzuje to, że obiekty w tych językach nie mają z góry ustalonego typu i dopiero w momencie wykonywania operacji na obiekcie sprawdzane jest, czy ta operacja jest możliwa. Mówiąc bardziej metaforycznie, języki skryptowe pozwolą na dodanie pięciu marchewek do samochodu i dopiero w trakcie działania wyrzucą wyjątek, podczas gdy języki statycznie typowane (w tym C++, Java, C#) w ogóle nie pozwolą na dodanie niekompatybilnych typów i zgłoszą błąd jeszcze na etapie kompilacji.

Istnieje wiele języków skryptowych, w tym najpopularniejsze to JavaScript, Python, Perl i  PHP. Ze względu na brak statycznego sprawdzenia kodu, języki dynamiczne wymagają dużej ilości testów automatycznych (w szczególności testów jednostkowych) i raczej nie nadają się do pisania rozbudowanych aplikacji. Gdy języki skryptowe wykorzystywane są np. w kontekście programowania w chmurze, najczęściej aplikacje tworzy się przez implementację wielu małych aplikacyjek, które współdziałają ze sobą, a każda z nich jest relatywnie mała i przez to łatwa do utrzymania.

Języki skryptowe znajdują swoje zastosowanie przede wszystkim w kontekście stron internetowych, aplikacji chmurowych, a także do automatyzacji czynności i pisania prostych programów w komputerach stacjonarnych. Języki skryptowe to także główna metoda testowania aplikacji napisanych w innych językach przy pomocy tzw. testów integracyjnych.