Co mě zaujalo na Google Go?

Logo
jazyka GoPřed několika dny Google vydal nový programovací jazyk Go (i když kdo ví, jestli se třeba nakonec nebude jmenovat jinak). Je určený pro systémové programování, je typově bezpečný (žádná ukazatelová aritmetika), paměť v něm spravuje garbage collector a obsahuje zabudovanou podporu pro paralelizaci.

Protože nové jazyky já rád, Go jsem samozřejmě prozkoumal a nabízím malý přehled toho, co mě na něm zaujalo. Snažil jsem se vybrat především věci, kterými se Go liší od jiných podobných jazyků, a zaměřil jsem se spíš na high-level záležitosti než na drobné detaily.

Zajímavé aspekty Go

Cíl

Cílem Go je usnadnit a zefektivnit systémové programování a přiblížit ho dnešním dynamickým jazykům. Ty nejsou zdaleka tak výkonné a typově bezpečné jako statické jazyky, ale mnohem snáz se v nich programuje, a tak k nim programátoři utíkají.

Osobnosti tvůrců

Myšlenkovými otci Go jsou mimo jiné Rob Pike a Ken Thompson. Tito pánové jsou zodpovědní za programovací jazyk C, operační systémy Unix a Plan 9 a také kódování UTF-8. Všechno poměrně dobře navržené a (až na Plan 9) i praktické a dodnes široce používané věci.

Rychlá kompilace

Kompilátor Go je ďábelsky rychlý – celá standardní knihovna se například zkompiluje za několik sekund. Rychlosti dociluje mimo jiné dvěma prostředky: efektivní prací se závislostmi jednotlivých částí programu a jednoduchou gramatikou jazyka.

Závislosti je v programu nutné explicitně deklarovat a kompilátor pak s těmito deklaracemi pracuje – především chytře zpracovává tranzitivní závislosti. Může tak při kompilaci a linkování krom zdrojového kódu načítat jen minimum souborů.

Jednoduchá gramatika jazyka nezrychluje jen kompilaci, ale zjednodušuje i další nástroje na práci s kódem (IDE, refaktorizační nástroje, tvůrce dokumentace aj.). V neposlední řadě je program přehlednější pro programátora. Autoři se zjevně poučili z příkladu C++, jehož parser je téma na diplomku.

Typový systém

Autoři vycházeli ze dvou myšlenek: je dobré důsledně oddělit rozhraní a implementaci a je špatné nutit programátory uspořádávat své třídy do hierarchií.

Obě myšlenky vedou k pojmu interface, který je v Go chápán jako množina metod. Jeho implementace je jakýkoliv typ, který danou sadu metod obsahuje. Podstatné je, že implementaci interfacu není nutné nijak deklarovat, vzniká implicitně na základě pouhé shody názvů a signatur metod. Velmi to připomíná duck typing známý z dynamických jazyků.

Zajímavá je práce s metodami: jsou to v podstatě obyčejné funkce, které mají jeden speciální parametr – příjemce. Jeho typ je chápán jako typ, ke kterému metoda patří. Není nutné, aby příjemce byl objekt (ty ostatně v Go jako prvek jazyka neexistují) – je tak možné definovat metody na jakémkoliv datovém typu a následně je volat na jeho hodnotách klasicky "přes tečku":

/* Definice typu Point */
type Point struct {
  X, Y float
}

/* Definice metody Scale na typu Point */
func (p *Point) Scale(factor float) {
  p.X *= factor;
  p.Y *= factor;
}

/* Použití */
x := &Point{ 3, 4 };
x.Scale(5);
Přímá podpora paralelizace v jazyce pomocí goroutines

Goroutines jsou běhová primitiva na rozhraní mezi procesem, vláknem a korutinou. Komunikace mezi nimi probíhá pomocí kanálů, inspirovaných formalismem CSP. Pokud aspoň trochu znáte Erlang, budou vám goroutines povědomé.

Goroutines jsou hlavní mechanismus, pomocí kterého je v Go podporována paralelizace. Runtime jazyka pracuje s goroutines velmi efektivně, není problém mít spuštěných například několik tisíc goroutines najednou.

Zajímavé je, že kanály, kterými goroutines komunikují, jsou úplně obyčejné hodnoty (jako třeba čísla či řetězce), takže je jde mimo jiné třeba také poslat kanálem :-)

Go nepodporuje spoustu běžných konceptů

Generiky/šablony, výjimky, aserce, přetěžování metod, přetěžování operátorů, implicitní numerické konverze... to vše v Go nenajdete. Důvodem je jednoduchost jazyka nebo negativní zkušenosti autorů s těmito konstrukcemi. Podrobněji je vše rozepsáno v dokumentaci.

Kód je povinně v UTF-8

Podpora Unicode je dnes u nových jazyků samozřejmost, ale Go je zajímavý tím, že zdrojový kód je vždy v kódování UTF-8. Odpadají tím zmatky při určení kódování zdrojového kódu, obvyklé u jiných jazyků.

Utilita gofmt

Autoři Go vyřešili všechny debaty ohledně stylu psaní kódu! Napsali totiž pretty-printer gofmt, který kód zformátuje do jednotné podoby. Je to poměrně sofistikovaný nástroj a řeší třeba i takové detaily jako správné odsazení komentářů za položkami struktury. Všechen zdrojový kód knihoven v Go je pomocí gofmt zformátován. Pokud má prý nějaký vývojář proti výsledku námitky, má je řešit s autory gofmt :-)

A co mě naopak nezaujalo?

Syntaxe

Syntaxe Go v zásadě vychází z céčka, ale obsahuje poměrně dost změn – kromě modifikací a nových prvků vynucených jazykem jde především o úpravu formátu deklarací (dle mého názoru dost nepovedenou) a nepovinné středníky a závorky na některých místech.

Bohužel syntaxe Go na mě dělá dojem jakéhosi hybridu – jako by se autoři snažili céčkovou syntaxi zpřehlednit a vyčistit od nepotřebných prvků, ale zároveň se nechtěli oprostit od klasických složených závorek. Navíc do syntaxe zavedli několik nehezkých věcí (například zbytečný operátor := a další význam závorek). Program napsaný v Go tak není příliš příjemný na čtení a nevypadá hezky.

Standardní knihovna

Autoři jsou zjevně zvyklí na céčko se svými spartánskými názvy a tak podobný styl na mnoha místech zachovali i v knihovnách Go. Já dávám přednost větší deskriptivnosti. Po stránce návrhu a funkcionality jsem knihovnu příliš nezkoumal.

Celkový dojem

Celkově mám z Go rozporuplný pocit. Na jednu stranu obsahuje řadu zajímavých myšlenek, ale na druhou stranu se autorům příliš nepovedla syntaxe a učinili řadu řekněme zvláštních návrhových rozhodnutí. Do jazyka také zavedli několik vyložených podivností (namátkou třeba určení viditelnosti metody podle velikosti prvního písmene jejího názvu, nebo konstrukce iota). Mít na výběr, tak bych v Go programovat asi spíš nechtěl.

Kde se dovědět víc?

Spousta dokumentace se dá najít na webu jazyka, přičemž nejzajímavější je asi Language Design FAQ. Pokud máte cca hodinu čas, doporučuju shlédnout hodinovou přednášku o Go přímo od jednoho z tvůrců:

Nov 13, 2009 – 13:49

Comments

Martin Hassman
Procházím si ukázky a myslím, že bych si na to dokázal zvyknout, ale mělo by to velkou učící křivku. Myslím pro ty syntaktické věci, co dělají opačně, než se dnes dělá (dlouho jsem třeba hledal, jak vlastně deklarují návratové hodnoty) a je pravda, že pořád nevidím důvod, proč otočili to pořadí typ hodnota, mě připadá, že to je jasně k horšímu a jsem zvědav, zda za tím opravdu je nějaký důvod, co proste nevidím.

A rozhodně bych nechtěl pracovat současně na dvou projektech, z nichž jeden bude v Go a jiný v nějakém C-like jazyku - to by mohl být slušný zabiják na hlavu.

Jsem zvědav, jak moc to rozšiřování Go ublíží. Jinak totiž sám o sobě (bez kontrastu se stávajícími zvyklostmi) nevypadá zle.

Pochopil jsem dobře, že se tenhle jazyk bude líbit všem, kteří volají, že "Dědičnost je zlo"?
optik
Nachlup stejný cíl jako Go má D (www.digitalmars.com). D je tu mnohem déle, má širokou komunitu, je multiplatformní ...., akorát s tím unicodem a paralelismem nevím. Škoda, že se D zatím moc neprosadil a asi neprosadí. Že je D pecka značí i to, že si ho všimly i takové kapacity jako Andrei Alexandrescu.
K.
K.
Taky mám z Go podobně rozporuplné pocity. Nějaké věci vypadají zajímavě, něco je dost WTF, něco je stejné jako v obvyklých jazycích *jenom naopak*.

Jinak viditelnost pomocí velkého prvního písmena mi přijde jako ohromný nápad (Ruby je na tom stejně). Tvůrci se holt nesnažili vytvořit manévrovací prostor v tom jak psát kód a zavedli Jediný Správný Standard. Což je dobře.

Něco v tom zkusím naprogramovat a uvidí se.
David Majda
[1] Ono zvyknout si člověk dokáže na lecos :-)

U deklarací mi mezi proměnnou a jejím typem hrozně moc chybí dvojtečka (jako ve starém dobrém Pascalu) - podle mě podobné oddělovače na správných místech hodně pomáhají čitelnosti a "skenovatelnosti" kódu (pokud nejsou v 99% redundantní s něčím jiným - viz středníky, za kterými typicky stejně následuje nový řádek).

Jinak ano, nepřátelé dědičnosti budou z Go určitě nadšeni.

[2] D jsem kdysi dávno letmo zkoumal a taky mi přijde škoda, že se neprosadilo šířeji. C++ si zaslouží vymýtit :-)
Martin
Martin
"Rob Pike a Ken Thompson ... jsou zodpovědní za programovací jazyk C" tak toto je pro mě novinka a podle všeho je to nesmysl. Jestli je někdo zodpovědný za C, tak K & R, spíše však jen samotný Ritchie.

Add comment

It is not possible to add comments to posts older than one month.