Ideální by bylo vyrobit si vlastní hardware, nebo alespoň umět ho vyrobit, kdyby bylo potřeba. Bohužel vyrobit dnešní hardware je složité. Dříve si studenti na amerických školách mohli v některých předmětech navrhnout vlastní procesor a ten se pak na konci semestru opravdu vyrobil. Bohužel dnes už to nejde, protože by to bylo prý moc drahé. Takže na výrobu vlastního hardwaru jsem zatím rezignoval.
Další krok je vyrobit vlastní software. Rád bych mu rozuměl. A abych rozuměl něčemu, co programuji, musím rozumět tomu jazyku. Ale čím víc se snažím rozumět jazyku, tím víc zjišťuji, že je příliš komplikovaný.
Teď už to bude 13 let, co jsem začal programovat v F# a stále mi ten jazyk nepřijde jednoduchý. Jednoduchý znamená, že rozumím všem konstrukcím v tom jazyce a umím ho i naimplementovat. Nevadilo by, kdyby ta implementace byla o něco málo pomalejší, ale musí být použitelná. Bohužel většina jazyků není jednoduchá.
Asi před 6 lety jsem si začal všímat, že F# začíná umírat. Začal jsem tedy hledat jeho alternativy. Soustředil jsem se více na jazyky, které nemají běhové prostředí. Z těch alternativ jsem nejvíce času strávil v jazycích Rust a C3. V obou z nich mám napsáno docela dost produkčního kódu. Jeden větší program jsem pak portoval z ImGui v C3 do egui v Rustu.
Rust se docela dost podobá F#. Hlavní výhodou je rychlost a pár velmi dobrých knihoven. Bohužel ale ani Rust není jednoduchý jazyk. Další věc je, že i standardní knihovna je komplikovaná. Osobně bych asi nezvládl naimplementovat ani základní strukturu, jakou je Box. A tohle mě odrazuje hodně. Třeba v .NET jsem části standardní knihovny pročetl a v principu tam většina kódu šla pochopit celkem snadno. Ztratil jsem se až v kódu GC, který má přes 100 tisíc řádků a k tomu invarianty, které znají asi jen jeho správci.
Rád dělám věci správně. Vstup a výstup by měl být asynchronní, což v Rustu by default není. Můžu použít Tokio a Async Rust, ale přeci nedává smysl, abych při každém vypisování řádku na terminál psal println!(..).await – jde mi o ten await. Přeci tohle by mělo být automaticky a všude. Skoro každý program dělá vstup a výstup, takže by měl být async. A Rust tohle dělá zbytečně složitým, stejně jako .NET i F#. Správně to má Go nebo Java 24 nebo OCaml 5.
Druhá věc je práce s chybami. Proč, když potřebuji základní věc, jakou vyhození a zachycení chyby je, proč potřebuji v Rustu další závislosti? Stejně jako F# má Rust jak výjimky aka panic, tak i vracení chyb pomocí Result. Když navíc použijete balíček anyhow, tak to druhé funguje celkem hezky. Škoda jen, že to nefunguje hezky out of the box.
Do třetice. Stojí borrow checker za to? V F# mám kód, který používá Rabbit MQ. Už funguje roky, ale nevím, jestli to není náhoda. Některé metody volám z různých vláken různě, tehdy dokumentace neuváděla, jestli můžu nebo ne, tak jsem na základě zkoumání implementace usoudil, že asi jo, ale přeci jen s tímhle bych se v Rustu netrápil. Takže stojí za to, ale bylo by fajn, kdyby někdo vymyslel, jak to udělat jednodušší – jak pro ty, co jazyk používají, tak pro ty, co jej implementují.
Kdyby byl jazyk Austral více známý, rád bych jej vyzkoušel. Je to takový jednodušší Rust. Ale přišlo mi, že to nemá cenu zkoušet, protože vypadá mrtvě.
Zjistil jsem, že můžu mít:
V jazyce Roc.
Roc je takové lepidlo. Každý program v Rocu dostane základní funkce, které jsou napsány v Rustu nebo Zigu nebo C. Tyto funkce pak používá.
Balíčku s těmito funkcemi se říká platforma. Programy pro příkazovou řádku používají jinou platformu než webové servery a ty používají jinou platformu než hry. Každá platforma má specializovaný alokátor, který se hodí pro daný typ programů.