Dnešní doba, a IT především, se vyznačuje tím, že vše chceme rychle. Možná právě proto se nový jazyk Go od Google prezentuje především svou rychlostí. Než se rozepíši podrobněji o tom jak vnímám jazyk Google Go, tak bych se již na začátku rád přiznal, že nejsem jeho velký znalec a žádný velký projekt jsem v něm nezrealizoval, proto chápejte následující řádky spíše jako první dojmy a pocity z používání nového jazyka než jako objektivní hodnocení.
Na stránkách jazyka Go naleznete tyto hlavní charakteristiky: bezpečnost, jednoduchost, rychlost, souběžnost (concurrency), open source. Ke každému z těchto rysů se pokusím alespoň částečně vyjádřit.
Jedním z hlavních cílů, které si autoři vytyčili, je typová a paměťová bezpečnost. Na úvod bych zmínil, že zatímco typový model se mi líbí, pojetí paměťové bezpečnosti se mi zdá nedotažené. Myšlenka zrušení typové hierarchie (přiznám se, že něčím podobným se zabývám již několik let) je podle mne krok správným směrem. Jelikož se Go řadí mezi objektové jazyky, je nutné se zamyslet nad tím, co si představíme pod pojmem objektové programování. V závislosti na autorovi lze najít různé definice s různými hlavními rysy. Já osobně považuji za nejlepší definici postulující pouze následující principy:
- objekt zapouzdřuje svá data
- objekt reaguje na zprávy
- objekt může obsahovat další objekty
Všimněte si, že zde zcela chybí dědičnost. Dle mého názoru není v objektovém programování vlastně vůbec potřeba (lze ji obejít např. agregací – 3. princip výše) a v moderních programovací jazyky, které používají časnou vazbu při volání metod, je využívána spíše jako technické řešení pro dosažení rychlého volání metod a pro stavbu typové hierarchie. V jazycích s pozdní vazbou slouží de-facto pouze ke stavbě typové hierarchie.
V jazyce Go jsou tedy splněny všechny 3 výše zmíněné body. Byť je řešení typové kompatibility přes interface elegantní, tak způsob, jakým je řešeno zapouzdření se mi nelíbí. Autoři oddělili typy (resp. data) a metody nejen fakticky, ale i syntakticky. Dneska hojně používaný způsob programování, kdy je implementace metod přímo v definici typu (např. Java, C#), se v Go nepoužívá. Metody daného typu mohou být definovány kdekoliv v balíčku (package), ve kterém je definován daný typ. Myslím, že tento přístup povede k nepřehlednému zdrojovému kódu, protože programátory nebude nic nutit dát metody na jedno místo.
Z důvodu paměťové bezpečnosti autoři samozřejmě zrušili pointerovou aritmetiku, ale vyhnuli se úplnému vyřešení problémů, které mohou nastat ve vícevláknovém prostředí (nebo v systému, kde funguje nějaká souběžnost). Ve FAQ se dočtete, že atomicita operací nebyla zatím plně definována.
Například jednou z oblastí, kde vidím potenciální problémy, je implementace map (struktura obsahující klíče a jejich hodnoty, obdoba např. Hashtable v C#). Mapy jsou konstrukty implementovány přímo v jazyce a operace nad nimi nejsou atomické. Tím pádem je plně v režii programátora zajistit, aby se k mapám přistupovalo pouze v jednom vlákně a nebo aby se použila explicitní synchronizace.
V jednoduchém projektu to asi problém nebude, ale ve větším projektu, který používá různé knihovny to problém být může. Zvláště pokud používáme vlákna a nebo souběžné go-routines – k čemuž jazyk de facto vybízí. Autoři sami přiznávají, že nesprávné použití může vést ke spadnutí aplikace. Doufejme, že tento fakt nevytváří prostor pro exploity.
Další věc, která mne zarazila (byť zde se jedná spíše o kvalitu prezentace než o kvalitu jazyka), byla, že když jsem se díval na prezentaci jazyka Google Go, tak téměř úplně na začátku ukazuje rychlost kompilace. Pokud to beru čistě pragmaticky, tak mi z toho vyplývá, že nejdůležitější vlastností tohoto jazyka je, že se dá velice rychle kompilovat. Nejsem si jist, že to je opravdu ta nejdůležitější vlastnost, kterou bych od nového moderního/revolučního jazyka čekal. Je zde přece celá řada jazyků, které kompilují dostatečně rychle (např. Python) a porovnávat Go s C a nebo C++ přece nemá význam.
Co se týče rychlosti a efektivnosti výsledného kódu, tak je asi zatím příliš brzo hodnotit. Chlapci z Googlu říkají, že program napsaný a přeložený pomocí Go je o 10 – 20 % pomalejší než stejný program v C. Nicméně už teď se dají na Internetu najít různé testy výkonnosti, které ukazují, že současné jazyky (včetně Javy a Pythonu) můžou být rychlejší než Go. Až časem se ukáže, jak to vlastně s výkonností Go doopravdy je.
A jak autoři splnili svůj cíl ohledně jednoduchosti? Zde je asi na místě se zeptat, pro koho má být tento jazyk jednoduchý. Myslím si, že pro programátory píšící např. v Javě, C#, Ruby, Pythonu bude Go těžkopádný a na druhou stranu pro céčkaře a C++kaře spíše peklo. Mě osobně syntaxe jazyka úplně odradila. Byť programuji v různých jazycích, zdrojový kód Go je pro mne velice špatně čitelný.
Chybí mi jednoduchá elegance, jakou má například Smalltalk. Na první pohled je patrná inspirace céčkem, ale nové konstrukce, otočení definice proměnných (jméno proměnné a pak typ),vynechání závorek u řídících struktur (např. místo klasického for(i=0;i<10;i++) je for i := 0; i < 10; i++
) a používání * a & je pro mne matoucí. Go se opravdu na první pohled podobá C, ale na druhou stranu se hodně liší. Je to podle mě tak nepovedený mix, že pokud byste měli programovat zároveň v C i v Go, tak to radši napište všechno v C#.
Zajímavou oblastí, kterou Go implementuje je souběžnost (conccurency). Jedná se de-facto o komunikaci založenou na typově bezpečných kanálech (inspirace v CSP – Communicating Sequential Processes – použité např. v Erlangu a Occamu). Tato myšlenka se mi velice líbí a jsem opravdu zvědav, jak to bude vypadat později v praxi a ve větších projektech. Zejména jak dobře budou dané projekty přehledné a jak dobře se budou ladit. S tím opět souvisí syntaxe by a ty by se dala, podle mne, vymyslet lépe. Například rozlišení směru komunikace podle infixu/prefixu mi nepřipadá šťastné.
Jelikož se však jedná o nový koncept, tak to zde nepůsobí tak bolestivě, jako změny oproti C popisované výše. Přístup k výjimkám a generickým typům, taktéž nepovažuji za rozumný. V této chvíli nejsou tyto vlastnosti implementovány z důvodů, jak píšou autoři, složitosti a nemožnosti nalezení vhodného modelu řešení. Dle mého názoru to, že autoři připouštějí, že stále uvažují o jejich implementaci ukazuje na to, že vlastně ani neví, jak by měl jejich jazyk vypadat. Z hlediska návrhu jazyka je toto zcela zásadní rozhodnutí, které zasahuje do kompatibility a způsobu programování. Zatímco přidání generických typů si snad představit lze – zde si vzpomeňte např. na Javu a .Net, i když se jedná o jazyky překládající do byte code – přidání výjimek by znamenalo zcela fundamentální změny (např. potřeba předělat knihovny tak, aby byly konzistentní). Doufají snad autoři v to, že otevřením projektu jako open source udělá komunita toto rozhodnutí za ně?
Co tedy dodat závěrem? Myslím si, že jazyk Go implementuje zajímavé myšlenky (např. typový systém, go-routines, kanály), ale celkově to prostě není ono. Nemám pocit: „WOW, v tom musím dělat“. Dnešní programovací jazyky nabízejí podobné (a nebo stejné) možnosti jako Go, ale navíc jsou otestované, rozšířené a mají širokou podporu. Jako by chlapci z Googlu trošku zaspali dobu.