Proč mám rád Rust
Programování je do značné míry boj s vlastní nedokonalostí a chybovostí. Kdo nehledal hodiny chybu středník versus dvojtečka?
Během své kariéry jsem pracoval s různými programovacími jazyky a paradigmaty. Každý z nich mě něco naučil – některé koncepty jsou více použitelné, jiné méně. Některé jazyky jsou lehké na pochopení, jiné doslova ničí mozkové buňky. Proč je Rust jedním z mých oblíbených jazyků?
Compile-time kontrola
Hodiny se přetahuji s kompilátorem, že toto je blbě, a tomuto nerozumí, a tamto... Ale jakmile se mi ho podaří přesvědčit, aby konečně dal pokoj, mám téměř jistotu, že můj kód bude fungovat. Takhle to u jiných jazyků – zvlášť ne u C/C++ – nefunguje. Je to spíše podobné Haskellu. Jen je Rust poněkud subtilnější.
V C++ je snadné napsat kód, který vypadá správně, ale skrývá zákeřné chyby, jako jsou use-after-free, race conditions nebo buffer overflows. (Prostě to spadne.) V Pythonu snadno předám do funkce/metody špatné hodnoty. (A pak to spadne. Nepo poškodí data.) Rust mě před těmito problémy chrání už při kompilaci.
V Rustu sice trávím více času vývojem, ale výsledkem je kód, který na 99 % funguje. V C, i když jsem zkušený vývojář, nikdy nemám jistotu, že kód poběží bez problémů v produkčním prostředí. Naopak většinu chyb totiž zjistím až tam – a to nemám rád.
Vyjadřovací schopnosti jazyka
Rust nabízí bohaté vyjadřovací možnosti, které u systémových jazyků absolutně nejsou normální. Pattern matching, iterátory, ownership a borrow checker. Rust kombinuje sílu nízkoúrovňového jazyka s moderními prvky, které známe z vyšších jazyků.
A nemyslím tím Javu, C# nebo Python. Spíše Haskell nebo Scalu.
Stručnost a přehlednost
Samozřejmě v porovnání s Pythonem je Rust mnohem „ukecanější“ (to dělají ty typové deklarace).
Přesto mi nějakým kouzlem umožňuje psát stručný a přehledný kód. Díky silné typové inferenci nemusím zbytečně specifikovat typy proměnných, když to není nutné. Výchozí klíčová slova mut a let udržují zápis jednoduchý a srozumitelný. Pattern matching a if let expressions jsou super.
Žádné Null hodnoty
Rust nepoužívá null. V jazycích jako C, C++, Java nebo Python je null častým zdrojem chyb, protože dereference null ukazatele/přístup na null hodnotu - často vede k neočekávaným pádům programu. Rust místo toho používá typ Option<T> a jemu podobné, který mě nutí vždy explicitně řešit případ nepřítomnosti hodnoty. Nemůže se tedy stát, že by můj kód selhal, protože jsem na null zapomněl.
Traity místo dědičnosti
Místo neosvědčené dědičnosti používá koncept "traitů" (podobně jako rozhraní v jiných jazycích - ale lepší). Díky tomu má Rust většinu konceptů z objektového programování – až na dědičnost.
Makra na vyšší úrovni
Makra v C/C++ (#define) fungují jako textové náhrady, což je nepřehledné a snadno vede k chybám. Rust používá makra na úrovni syntaktického stromu (macro_rules!), takže kompilátor chápe, co se děje. Může validovat, optimalizovat a chyby ukazuje tam, kde skutečně jsou.
Srozumitelné chybové zprávy
Rust je nemilosrdný. Jakákoli nejasnost nebo nejednoznačnost vede k chybě kompilace. Ale když kompilátor narazí na problém, neposkytne mi jen strohou hlášku a záplavu čísel, jako v C/C++, nebo nekonečný stack trace, jako v Javě či C#. Místo toho Rust poskytuje detailní a srozumitelné chybové zprávy, které často obsahují i návrhy na opravu.
Například pokud Rust zjistí chybu v pravidlech ownershipu nebo lifetimů, nejenže mi řekne, kde k ní došlo, ale také vizuálně zvýrazní problematickou část kódu a nabídne řešení. To je doslova návykové.
Ekosystém a nástroje
Nástroje jako cargo a crates.io zjednodušují správu závislostí, balíčkování a automatizované testování, které je přímo součástí jazyka.
Rychlost a binárky
Rust je nízkoúrovňový jazyk, který kompiluje do binárky. Do jedné. Do té, kterou potom pošlu klientovi.
Příklad z praxe
Kdysi jsem měl aplikaci, která byla vlastně jen XSLT šablona pro transformaci XML. Přepsal jsem ji do Rustu a jednotlivé XML exporty generoval pomocí funkcí. Práce s tím nakonec bylo méně než s XSLT, výsledek byl přehlednější a získal jsem bonus v podobě jednodušší distribuce. Místo složitého návodu jsem klientovi předal pohodlnou binárku.
Závěr
Rust má svou cenu – je třeba se ho naučit a smířit se s jeho přísnými pravidly. Hodí se mít prášky proti bolesti hlavy.
Získám ale neuvěřitelnou jistotu, že můj kód bude správný a bezpečný (a rychlý).