Języki programowania – kto odpowiednio długo przesiadywał w świecie komputerów, ten zapewne – choćby przez przypadek – kiedyś o nich usłyszał. Ci, którzy trochę bardziej zainteresowali się informatyką, stopniowo je poznają. Odkrywają Javę, Pythona, JavaScript, SQL, C++ – z czasem okazuje się, że jest ich naprawdę wiele. Jeśli mijają lata, a ciekawość i chęć zawodowego rozwoju nie słabnie, to jasne stają się pewne podziały i zależności między językami.
Doświadczeni deweloperzy mają często swoje osobiste preferencje i antypatie: pewnych schematów po prostu nie znoszą. Potrafią się nawet latami kłócić o to, który język jest lepszy i pod jakim względem. Wystarczy wyszukać w sieci “najlepszy język programowania” lub “Java kontra C#”, aby znaleźć setki dyskusji i artykułów na ten temat. Tak zatem prędzej czy później często pojawia się pytanie: dlaczego tych języków powstało aż tyle? Aby poszukać odpowiedzi, cofnijmy się najpierw do początków.
Języki programowania – pionierzy
Nikt nie twierdzi, że programowanie jest szczególnie łatwe, jednak na u zarania historii komputerów było niesamowicie uciążliwe. Języki pierwszej generacji to czysty kod maszynowy, czyli ciągi zer i jedynek bezpośrednio odczytywane przez procesor. Praca z takimi programami wymaga ogromnej skrupulatności, gdyż najmniejszy błąd może być niemal niemożliwy do odnalezienia. Zrozumiałe zatem jest, że bardzo wcześnie usiłowano ułatwić sobie życie przez zastąpienie często używanych ciągów liczb binarnych pewnymi symbolami. W ten sposób (jeszcze w latach 40.) narodziły się języki drugiej generacji, potocznie zwane asemblerami. Są to w zasadzie listy pojedynczych instrukcji dla procesora, możliwe do odczytania w ludzkim języku, np.: “załaduj liczbę 17 do rejestru o adresie 0x02”. Zaleta? Nie trzeba pamiętać kodu binarnego tej operacji. Wada? Autor programu musi osobiście używać komend zrozumiałych dla CPU. Oznacza to, że aby nauczyć się programować wydajnie, trzeba go poznać od podszewki, czyli nauczyć się jego instruction set – zestawu obsługiwanych instrukcji. Każdy model procesora ma zatem nieco odmienny, właściwy sobie asembler! To podstawowa przyczyna powstawania kolejnych takich języków. Nie trzeba mówić, że to rozwiązanie też było uciążliwe. Dlatego stworzono dalsze generacje.
Języki programowania wysokiego poziomu
Od tego momentu naprawdę się zaczęło. Podstawowa idea, przyświecająca językom generacji trzeciej, czwartej i piątej to większa czytelność kodu dla człowieka oraz jego uniezależnienie od architektury procesora. Rzecz w tym, że pojawiło się mnóstwo koncepcji, jak to zrealizować! Nie znaczy to wcale, że języki są bezwzględnie dobre lub złe. W większości przypadków zależy to od mnóstwa czynników:
- czytelność kodu źródłowego,
- łatwość debugowania,
- przystosowanie do pisania testów,
- intuicyjność składni,
- dostępne biblioteki i frameworki,
- istniejące kompilatory i środowiska programistyczne,
- wsparcie przez firmę lub społeczność,
- wszechstronność zastosowań,
- dostosowanie do wielowątkowości,
- wysoka optymalizacja pisanych programów,
- łatwość nauki języka (dla nowicjuszy i doświadczonych),
- możliwość szybkiego napisania programu,
- wysoka specjalizacja w konkretnej dziedzinie
(matematyka, bazy danych, technologie webowe, sterowniki sprzętowe, systemy pomiarowe, przetwarzanie tekstu, tworzenie grafik… ).
Lista jest długa i bynajmniej nie kompletna. Tak wielu kryteriów nie da się spełnić na raz. Dlatego za każdym językiem kryje się długa historia ludzi i ich maszyn.
Języki programowania: przystępność, czyli co?
Czytelność, łatwość pisania i debugowania kodu, intuicyjność składni – różnie można to opisywać, a w sumie chodzi o to, czy dany język jest “przyjazny”. Pisanie programu to w zasadzie przelewanie myśli na pismo. Tutaj ważna uwaga: największą odpowiedzialność za to ponosi nie kto inny, jak autor kodu. To zupełnie jak z ludzką mową: można posługiwać się nią z erudycją lub niechlujstwem. Przede wszystkim zależy to właśnie od mówcy. Istnieją jednak języki brzmiące śpiewnie i twardo, zwięzłe i rozwlekłe, zawiłe i proste.
Ta analogia nasunęła pomysł, aby wzorować języki programowania na angielskim (gdyż ich twórcy byli w dużej części Amerykanami). Nie zawsze przynosiło to pożądane rezultaty, np. w COBOL-u. Jego składnia miała być przystępna, ale okazała się raczej rozwlekła i utrudniająca pisanie. Z innej strony, programy to realizacje algorytmów, czyli pewnych logicznych, matematycznych operacji. Stąd wzięły się analogie do symboli matematycznych, np.:
- używanie działań arytmetycznych,
- nawiasy przy użyciu funkcji,
- klamry dla grupowania wyrażeń.
Pewnym wyjątkiem jest znak “=”. W matematyce i np. języku Pascal oznacza porównanie, ale w większości innych jest to przypisanie. To jeden z licznych niuansów, ważnych przy nauce. Co ciekawe, oznacza to, że te języki rzucają kłodę pod nogi zawodowym matematykom, wymagając od nich zmiany bardzo podstawowego przyzwyczajenia.
Inne podejście to korzystanie z wcześniej spopularyzowanych elementów. Dlatego tak liczne są podobieństwa między językami, bo nowsze czerpały ze starszych. W bardzo wielu z nich łatwo jest rozpoznać:
- wyrażenia warunkowe (if),
- pętle (for i while),
- instrukcję skoku (goto),
- wywołanie funkcji/ procedury/ subrutyny (nawiasy okrągłe),
- operatory logiczne (&& to koniunkcja, || – alternatywa).
Niebagatelne znaczenie ma łatwość nauczenia się nowego języka. Wiele już pisano o tym, który język jest najlepszy dla początkujących. Dość często wymieniane są tu Python i JavaScript, ale istotny jest również C – to dobra podstawa dla dalszej nauki.
Ważne jest zaplecze
Największy geniusz twórczy nie wystarczy, aby nowe języki programowania dobrze sprawdzały się w praktyce. Trzeba jeszcze stworzyć dla nich kompilatory (lub interpretery) i co więcej – dbać o ich rozwój. Są to w zasadzie tłumacze kodu. Działają według składni języka, muszą więc mieć ją dobrze zakodowaną. Ale same są jakimiś programami, więc jest niezmiernie ważne, aby nie miały żadnych błędów. Nic tak nie odstręcza od nauki języka, niż rażące niezgodności między teorią (czyli nauczoną składnią) a praktyką (czyli wynikiem kompilacji). Stworzenie bezbłędnego kompilatora, w dodatku szybkiego w działaniu i tworzącego zoptymalizowany, wydajny kod maszynowy to wielkie wyzwanie. A jeszcze trudniejsze jest jego utrzymanie, wydawanie kolejnych wersji, aktualizowanie. Praktycznie zawsze przerasta to możliwości jednego człowieka. Dlatego poważne, znane kompilatory – a przez to również języki programowania – można podzielić na dwie grupy:
Otwarte – wspierane przez społeczność, do której może dołączyć każdy. Dzięki temu każdy niuans może być publicznie przedyskutowany. Trudniej jednak o koordynację prac i regularne aktualizacje. Takie są niemal wszystkie współcześnie najpopularniejsze języki.
Zamknięte – będące własnością konkretnej organizacji, która dba o jego rozwój. Może ona być gwarantem dla stabilnej przyszłości, ale może też utajnić szczegóły implementacji. Obecnie dotyczy to w większości bardziej niszowych, specjalistycznych języków.
Zaplecze języka to oczywiście nie tylko kompilatory, ale i środowiska programistyczne, które również mogą być dostępne na licencji open source lub odpłatnie. Różnią się one wydajnością, wyglądem interfejsu, dostępnymi narzędziami do nawigacji, debugowania i organizacji projektu, pluginami, wspieranymi językami – długo by wymieniać. Wybór środowiska to więc osobna sprawa.
Podsumowanie
Konkluzja jest jedna: kolejne języki powstawały, aby ułatwić ludziom życie. Zazwyczaj matką wynalazku była potrzeba: gdy doświadczony deweloper (uczelnia, ośrodek badawczy, firma) bardzo chciał rozwiązania, które jeszcze nie istniało – tworzył je sobie. Często był to tylko jakiś skrypt, który np. znajdował automatycznie błędy w trudnym kawałku kodu, albo tłumaczył proste komendy na skomplikowany program. Ale czasem problem był poważniejszy i historia jego rozwiązania toczyła się dalej, aż do powstania nowego języka. Tak dla stron internetowych stworzono PHP i JavaScript, dla programowania obiektowego powstały m.in. C++ i Java. Do operacji na macierzach jest MATLAB, do przetwarzania tekstu wymyślono Perla, do opisu sprzętu – VHDL. Bazy danych obsługuje SQL, makra w pakiecie MS Office – Visual Basic. Python i bash mogą służyć do tworzenia pomocnych skryptów.
Mimo przytłaczającej mnogości języków i ich zastosowań nie ma powodu się zniechęcać. Dobrze jest wybrać jeden do nauki na początek i po prostu nabierać doświadczenia. Kolejne nadejdą niemal nieuchronnie, a z czasem ich poznawanie będzie coraz łatwiejsze. Grunt, to znaleźć dobre narzędzie dla konkretnego zagadnienia. A jeśli się nie uda? Cóż, zawsze można stworzyć nowe…
Marketingowiec Front-endowcem