Obsah
1. Dyon – spojení předností Rustu a dynamicky typovaných programovacích jazyků
2. Instalace Dyonu s využitím správce projektů Cargo
5. Ukázka konstruktorů základních datových typů
7. Funkce s parametry a „matematická notace“
8. Změna parametrů ve volaných funkcích
11. Řídicí (rozhodovací) konstrukce
13. Zkrácený zápis smyčky: automatické odvození, přes kterou sekvenci se iteruje
14. Zkrácený zápis vnořených smyček
15. Zápis často používaných typů smyček – suma, hledání maxima atd.
16. Repositář s demonstračními příklady
1. Dyon – spojení předností Rustu a dynamicky typovaných programovacích jazyků
„If you need OOP patterns, then there is only one solution: Use another language, for example Rust. Dyon is designed for scripting, as in solving problems fast. It is not designed for building abstractions, or proving things through the type system.“
Při vývoji herního enginu Piston vznikl mj. i poměrně zajímavý programovací jazyk nazvaný Dyon (tento název je odvozen od hypotetické částice). Důvodem pro vznik Dyonu byla především snaha o vytvoření flexibilního jazyka pro rustovský ekosystém, v němž by se navíc měly uplatnit ty nejzajímavější koncepty Rustu, především dealokace objektů na základě analýzy jejich viditelnosti/životnosti, nikoli s použitím klasického správce paměti (garbage collectoru). Dyon sice používá dynamické typování, ovšem umožňuje i plnou specifikaci datových typů (například parametrů funkcí) a navíc kontroluje, zda se nemění datový typ hodnot přiřazovaných do jedné proměnné.
Poznámka: Dyon nelze považovat za univerzální programovací jazyk, který má ambice nahradit dnes populární skriptovací jazyky. Skutečně se na něj musíme dívat jako na doplněk k Rustu u těch částí aplikace, kde se nechceme do podrobností zabývat (mnohdy „zapeklitým“) typovým systémem Rustu.
Mj. i díky dobré kooperaci mezi Rustem a Dyonem je dnes možné vyvíjet aplikace používající oba zmíněné jazyky: Rust spíše pro nízkoúrovňové operace popř. pro implementaci základního engine a Dyon ve funkci „lepidla“ komponent. Ostatně podobný koncept dvou jazyků nalezneme i v dalších oblastech, dnes typicky u dvojice C+Python či Java+Groovy, Java+Clojure apod.
Kromě sledování životnosti proměnných najdeme v Dyonu i další koncepty převzaté z Rustu (a někdy i vylepšené). Jedná se například o použití typů Result a Option, pro něž byl navíc vytvořen speciální operátor atd.
2. Instalace Dyonu s využitím správce projektů Cargo
Instalace programovacího jazyka Dyon je pro zkušenější rustovské programátory triviální, protože je tento jazyk dostupný ve formě balíčku spravovaného systémem Cargo. Postačí si tedy vytvořit nový projekt a do něj do sekce se závislostmi přidat jedinou knihovnu.
Prvním krokem je samozřejmě vytvoření projektu:
$ cargo new --bin dyon-hello-world
Dále upravíme projektový soubor přidáním sekce [dependencies]:
[package] name = "dyon-hello-world" version = "0.1.0" authors = ["Pavel Tisnovsky <ptisnovs@redhat.com>"] [dependencies] dyon = "0.21.0"
Pokud nyní spustíme překlad projektu, stáhnou se všechny potřebné balíčky, na nichž Dyon závisí, a následně se tyto balíčky přeloží:
$ cargo build
Updating registry `https://github.com/rust-lang/crates.io-index` Downloading dyon v0.21.1 Downloading piston_meta v0.29.1 Downloading rand v0.3.16 Downloading range v0.3.1 Downloading read_color v0.1.0 Downloading read_token v0.9.0 Downloading hyper v0.9.18 Downloading libc v0.2.29 Downloading log v0.3.8 Downloading rustc-serialize v0.3.24 Downloading unicase v1.4.2 Downloading httparse v1.2.3 Downloading num_cpus v1.6.2 Downloading language-tags v0.2.2 Downloading url v1.5.1 Downloading traitobject v0.0.1 Downloading typeable v0.1.2 Downloading time v0.1.38 Downloading cookie v0.2.5 Downloading solicit v0.4.4 Downloading mime v0.2.6 Downloading version_check v0.1.3 Downloading percent-encoding v1.0.0 Downloading idna v0.1.4 Downloading unicode-bidi v0.3.4 Downloading hpack v0.2.0 Compiling matches v0.1.6 Compiling lazy_static v0.2.8 Compiling range v0.3.1 Compiling libc v0.2.29 Compiling typeable v0.1.2 Compiling read_color v0.1.0 Compiling unicode-normalization v0.1.5 Compiling language-tags v0.2.2 Compiling log v0.3.8 Compiling httparse v1.2.3 Compiling version_check v0.1.3 Compiling rustc-serialize v0.3.24 Compiling percent-encoding v1.0.0 Compiling traitobject v0.0.1 Compiling unicode-bidi v0.3.4 Compiling read_token v0.9.0 Compiling time v0.1.38 Compiling num_cpus v1.6.2 Compiling rand v0.3.16 Compiling mime v0.2.6 Compiling hpack v0.2.0 Compiling unicase v1.4.2 Compiling piston_meta v0.29.1 Compiling idna v0.1.4 Compiling solicit v0.4.4 Compiling url v1.5.1 Compiling cookie v0.2.5 Compiling hyper v0.9.18 Compiling dyon v0.21.1 Compiling dyon-project v0.1.0 (file:///home/tester/rust/projects/dyon-project) Finished dev [unoptimized + debuginfo] target(s) in 64.83 secs
Do souboru main.rs přidáme kód pro spuštění nového skriptu napsaného v jazyce Dyon:
extern crate dyon; use dyon::{error, run}; fn main() { error(run("src/main.dyon")); }
Vytvoříme zmíněný skript main.dyon, který je prozatím velmi jednoduchý:
fn main() { println("Hello world!") }
Celou aplikaci by nyní mělo být možné přeložit a spustit:
$ cargo run
Compiling dyon-project v0.1.0 (file:///home/tester/temp/presentations/rust/projects/dyon-project) Finished dev [unoptimized + debuginfo] target(s) in 2.9 secs Running `target/debug/dyon-project` Hello world!
3. Proměnné
Proměnné se v Dyonu vytváří velmi jednoduše, dokonce ještě jednodušeji než v Rustu. Celá deklarace proměnné spočívá v uvedení jejího názvu, znaků := pro přiřazení a hodnoty, která se má do proměnné přiřadit. Hodnota je samozřejmě nějakého typu, ze kterého je automaticky odvozen i typ výsledné proměnné:
x := 42
Obsah proměnných je možné měnit, což znamená, že proměnné nejsou ve výchozím nastavení neměnitelné (immutable). Pro změnu obsahu proměnné se používá odlišný znak přiřazení =, nikoli :=. Díky této maličkosti je možné detekovat chyby způsobené překlepem ve jménu proměnné:
x = 0
Při přiřazování hodnot do proměnných se provádí kontroly, zda proměnná již existuje (tj. zda byla deklarována) a současně zda má nová hodnota typ shodný s typem proměnné. To je jeden z podstatných rozdílů oproti dalším dynamicky typovaným jazykům, u nichž je většinou možné do proměnných přiřazovat hodnoty různých typů. Příkladem může být dynamicky typovaný Python:
x=True x=42 x="xyzzy" x=(1,2,3)
Mezi chybné zápisy patří:
b = 42
Chyba:
--- ERROR --- In `src/main.dyon`: Could not find declaration of `b` 3,5: b = 42 3,5: ^
Dále pak pokus o přiřazení hodnoty jiného typu:
a := 42 a = "xyzzy"
Chyba:
--- ERROR --- main (src/main.dyon) variables (src/main.dyon) Expected assigning to text 3,5: a = "xyzzy" 3,5: ^
Naproti tomu lze vytvořit novou proměnnou stejného jména, ta ovlivní viditelnost a životnost původní proměnné:
a := 42 a := "xyzzy"
4. Datové typy
V jazyku Dyon nalezneme poměrně velké množství datových typů, zejména:
- Logické hodnoty true a false reprezentované typem bool.
- Čísla, která interně odpovídají typu f64 z Rustu. Při zápisu je možné oddělovat tisíce, miliony atd. podtržítkem, což zvyšuje čitelnost.
- Řetězce, které odpovídají typu str, tj. používá se kódování UTF-8 atd.
- Heterogenní pole s prvky zapisovanými do hranatých závorek [].
- Seznamy (links), což jsou v podstatě homogenní pole alokovaná po blocích o velikosti 1 kB. K prvkům seznamů se přistupuje funkcemi head a tail.
- Čtyřrozměrné vektory, kde ovšem třetí a čtvrtá složka mohou být implicitně nulové, takže je lze použít i jako 2D a 3D vektory. Důvod použití: prakticky všechny grafické algoritmy. Prvky vektorů se zapisují do kulatých závorek.
- Objekty (objects), ve skutečnosti se ale jedná o slovníky.
- Uzávěry (closures), o nichž se zmíníme dále.
- Typ Option známý z Rustu.
- Typ Result známý opět z Rustu.
5. Ukázka konstruktorů základních datových typů
Podívejme se na příklad, který osvětlí použití (především konstrukci) základních datových typů:
a := true println(a) b := 42 println(b) c := 1_000_000 println(c) // 4D vektor d := (1,2,3,4) println(d) // 3D vektor e := (1,2,3) println(e) // 2D vektor f := (1,2) println(f) // skalár! (jen umístěný do závorek) g := (1) println(g) // heterogenní pole h := [1,2,3,4,true,"xyzzy"] println(h) // seznam i := link{1 2 3 4} println(i) println(head(i)) println(tail(i)) println(head(tail(i))) println(tail(tail(i))) s := "Hello" println(s)
Výsledky:
true 42 1000000 (1, 2, 3, 4) (1, 2, 3) (1, 2) 1 [1, 2, 3, 4, true, "xyzzy"] 1234 some(1) 234 some(2) 34 Hello
Poznámka: prvky seznamů jsou tisknuty za sebou bez mezer.
6. Funkce
Programovací jazyk Dyon má – ostatně podobně jako samotný Rust – některé funkcionální rysy, takže nás pravděpodobně asi nepřekvapí, že se v tomto jazyce velmi dobře a snadno pracuje s funkcemi, navíc je hlídáno správné použití návratových hodnot funkcí apod. Funkce se mohou deklarovat několika způsoby, přičemž základní způsob se v mnoha ohledech podobá samotnému Rustu. Funkce bez parametrů, která nevrací žádnou hodnotu (jde tedy vlastně o proceduru a nikoli plnohodnotnou funkci) bude vypadat takto:
fn funkce1() { println("funkce1") }
Pokud chceme vytvořit funkci, která vrací hodnotu, je nutné před blok s tělem zapsat → a současně je nutné ve funkci použít return. Nelze se tedy spolehnout na to, že poslední výraz ve funkci po svém vyhodnocení vytvoří návratovou hodnotu, která se použije automaticky! Současně se musí návratová hodnota funkce „zkonzumovat“. Podívejme se na příklad:
fn funkce2() -> { println("funkce2") return 42 } fn functions() { print(funkce2()) }
Následující úryvky kódu jsou chybné:
fn funkce2() -> { println("funkce2") 42 }
Chyba vypsaná při spuštění – očekává se explicitní vrácení hodnoty:
--- ERROR --- In `src/main.dyon`: Type mismatch (#775): Expected `any`, found `void` 5,1: fn funkce2() -> { 5,1: ^ 6,1: println("funkce2") 7,1: 42 8,1: }
fn funkce2() { println("funkce2") return 42 }
Chyba vypsaná při spuštění – zde se naopak příkaz return vůbec neočekává:
--- ERROR --- In `src/main.dyon`: Type mismatch (#350): Expected `void`, found `f64` 7,12: return 42 7,12: ^
fn funkce2() -> { println("funkce2") return 42 } fn functions() { funkce2() }
Zde se „nezkonzumovala“ návratová hodnota funkce:
--- ERROR --- In `src/main.dyon`: Type mismatch (#1100): Unused result `any` 12,5: funkce2() 12,5: ^
7. Funkce s parametry a „matematická notace“
Funkce s parametry se zapisuje běžným způsobem, přičemž většinou nepotřebujeme explicitně specifikovat typy parametrů:
fn funkce3(x,y) -> { return x*y } ... ... ... println(funkce3(6,7))
Existuje ovšem i další a podle mého názoru mnohem zajímavější způsob deklarace funkcí, který autor Dyanu nazval „matematická notace“. Zde se vynechává klíčové slovo fn, explicitní zápis → i klíčového slova return a zápis se zjednoduší na jediný řádek:
funkce4(x,y) = x*y
Volání této funkce se již nijak neliší od volání předchozí funkce:
println(funkce4(6,7))
Konstrukci if-else lze použít i ve výrazu, takže můžeme tvořit i složitější one-linery, například:
inv(x) = if x!=0 {1.0/x} else {0}
Příklad volání:
println(inv(0)) 0 println(inv(2)) 0.5
Samozřejmě můžeme použít i rekurzi (v současnosti bez optimalizací):
factorial(n) = if n <= 1 { 1 } else {n * factorial(n-1)}
8. Změna parametrů ve volaných funkcích
Funkce mohou měnit hodnoty svých argumentů, ale v tomto případě se jedná o poměrně problematický rys, který musí být explicitně specifikován jak při deklaraci funkce, tak i při jejím volání. Konkrétně to znamená, že u jména argumentu i parametru musí být zapsáno klíčové slovo mut:
fn inc(mut x) { x += 1 } x := 1 println(x) inc(mut x) println(x) inc(mut x) println(x) 1 2 3
Použití mut se poměrně striktně hlídá a pokud toto slovo nepoužijeme, dostaneme následující chybové hlášení:
--- ERROR --- In `src/main.dyon`: Requires `mut x` 22,5: x += 1 22,5: ^
9. Programové bloky
Základním stavebním prvkem všech aplikací naprogramovaných v Dyonu jsou kromě již výše zmíněných funkcí i bloky, které se již z historických důvodů (viz především programovací jazyky B a C) zapisují mezi složené závorky { a }. Ovšem bloky se v Dyonu, podobně jako v Rustu, chovají jako výrazy, přičemž hodnota posledního výrazu v bloku je současně i návratovou hodnotou celého bloku. Připomeňme si, že se v Dyonu nemusí používat středníky, takže zde nenastává stejný problém jako například v samotném Rustu, kde je velký rozdíl mezi ukončením posledního výrazu středníkem a uvedením stejného výrazu, ovšem bez středníku. Podívejme se nyní na použití jednoduchých bloků (s jedním výrazem) i poněkud složitějších bloků, v nichž je uvedeno větší množství výrazů:
fn blocks() { u := 42 println(u) v := {42} println(v) w := {6*7} println(w) x := {u*v} println(x) y := { a := 6 b := 7 a*b } println(y) z := { a := 6 b := 7 if a<b { a*b } else { 0 } } println(z) }
Výsledky:
42 42 42 1764 42 42
Musíme si však dát pozor na životnost proměnné (viz též další text, kde se budeme touto problematikou zabývat). Následující příklad skončí s chybou, protože se snažíme proměnnou použít mimo oblast její životnosti:
fn blocks_error() { x := { y := 42 y } println(x) }
Chyba, která nastane při překladu:
--- ERROR --- In `src/main.dyon`: `y` does not live long enough 34,10: x := { 34,10: ^ 35,1: y := 42 36,1: y 37,1: }
Jedno z řešení spočívá v naklonování reference na hodnotu:
fn blocks_clone() { x := { y := 42 clone(y) } println(x) }
10. Uzávěry
Podobným způsobem jako funkce se zapisují i uzávěry (closures), při jejichž volání se musí použít znak \ (připomínající lambdu):
f := \(x,y) = x*y println(\f(6,7))
Složitější uzávěr:
fac := \(n) = if n <= 1 { 1 } else {n * factorial(n-1)}
Do uzávěru lze přidat hodnotu (nepředávanou parametrem při jeho volání) s použitím grab:
delta := 6 f := \(x) = x * (grab delta) println(\f(7)) 42
Popravdě: práce s uzávěry není až tak elegantní, jak by tomu mohlo být při použití odlišného způsobu zápisu.
11. Řídicí (rozhodovací) konstrukce
Základní řídicí konstrukcí je v programovacím jazyku Dyon samozřejmě konstrukce typu if-then popř. if-then-else. Ta se zapisuje prakticky stejným způsobem, jaký známe z Rustu, tj. okolo vyhodnocovaného výrazu se nemusí psát kulaté závorky, ovšem všechny příkazy ve větvích then a else naopak musí být uzavřeny do blokových závorek { a }, a to i tehdy, pokud je celý blok tvořen jediným příkazem. Nejjednodušší tvar řídicí konstrukce if-then je následující:
x := 1 if x < 0 { println("zaporny") }
Úplný tvar konstrukce if-then-else pak vypadá takto:
x := 1 if x < 0 { println("zaporny") } else { println("nezaporny") }
V případě potřeby je možné zřetězit větší množství podmínek za sebe. Používaný způsob zápisu je následující:
x := 1 if x < 0 { println("zaporny") } else if x == 0 { println("nulovy") } else { println("kladny") }
Vzhledem k tomu, že blok je považovaný za výraz, který může vracet hodnotu, platí to stejné i pro celou rozhodovací konstrukci if-then, kterou lze použít všude tam, kde je očekávaný výraz:
x := 1 println(if x < 0 {"zaporny"} else {"nezaporny"})
Totéž samozřejmě platí i pro úplnou konstrukci if-then-else:
x := 1 println(if x < 0 {"zaporny"} else if x == 0 {"nulovy"} else {"kladny"})
Poznámka: vzhledem k tomu, že je možné rozhodovací konstrukci použít ve výrazu, nebylo nutné do Dyonu přidávat podporu pro poněkud méně čitelný ternární operátor ?:.
12. Programové smyčky
Programové smyčky hrají v jazyku Dyon velmi významnou roli, takže jich zde najdeme poměrně velké množství a navíc je speciálně programová smyčka for navržena takovým způsobem, aby ji bylo možné různými způsoby zkracovat. Nicméně začněme tou nejjednodušší smyčkou, která se jmenuje přímočaře loop. Jedná se o nekonečnou smyčku, která neobsahuje žádnou podmínku ani řídicí proměnnou. Jediná možnost, jak tuto smyčku ukončit, spočívá v použití příkazu break, který zde má stejný význam, jako je tomu v dalších programovacích jazycích odvozených od céčka. Podívejme se na typický (školní) příklad smyčky, která na standardní výstup vypíše hodnoty 0 až 10. Tuto smyčku lze realizovat následovně:
x := 0 loop { println(x) x += 1 if x > 10 {break} }
Výstup:
0 1 2 3 4 5 6 7 8 9 10
V Dyonu nalezneme i počítanou smyčku typu for, kterou lze použít různými způsoby. Podporována je především sémantika podobná céčku (či Javě), kdy se vytvoří (deklaruje) řídicí proměnná smyčky, dále se specifikuje podmínka pro ukončení smyčky a taktéž iterační příkaz provedený vždy na konci každé iterace. Jednotlivé výrazy (deklarace, podmínka, iterační příkaz) se od sebe oddělují středníkem a tělo smyčky je umístěno do bloku ohraničeného závorkami { a }:
for x := 1; x < 1000; x *= 2 { println(x) }
Tato smyčka vypíše mocniny dvou:
1 2 4 8 16 32 64 128 256 512
V mnoha případech se smyčka for používá pro vytvoření posloupnosti celých čísel. Samozřejmě je možné použít zápis:
for i := 0; i < 10; i += 1 { println(i) }
Ovšem to je zbytečně zdlouhavé a především se v množství kódu ztrácí původní idea. Z tohoto důvodu se dá v jazyku Dyon použít zkrácený zápis, kdy se uvede jen horní mez posloupnosti. Řídicí proměnná v takovém případě nabývá hodnot 0, 1, 2 … mez-1:
for i 10 { println(i) }
Výstup:
0 1 2 3 4 5 6 7 8 9
Pokud je zapotřebí, aby posloupnost nezačínala nulou, používá se v programovacích jazycích dosti neobvyklý zápis, který ale připomíná matematický zápis intervalu. Povšimněte si, že první závorka je hranatá a druhá kulatá (v matematice se při zápisu intervalu používají úhlové a kulaté závorky):
for i [10,20) { println(i) }
Výstupem bude v tomto případě řada celých čísel od 10 (včetně) do 20 (kromě):
10 11 12 13 14 15 16 17 18 19
13. Zkrácený zápis smyčky: automatické odvození, přes kterou sekvenci se iteruje
U těch programových smyček, v nichž se prochází polem (ovšem nikoli již vektorem nebo seznamem!) je možné použít zkrácený zápis, v němž se uvede pouze jméno řídicí proměnné a nikoli již požadovaný rozsah hodnot. Ten je automaticky zjištěn z těla smyčky podle toho, jak se řídicí proměnná používá. Zpočátku to může vypadat „magicky“, ovšem ve skutečnosti se jedná o užitečnou vlastnost.
V následujícím zápisu je automaticky zjištěno, že i musí nabývat hodnot od 0 do 3:
a := [1,2,3,10] for i { println(a[i]) }
Ve složitějším kódu, kde je řídicí proměnná použita pro indexování většího množství polí, se použije velikost prvního pole ve výrazu. To znamená, že následující kód bude funkční a vypíše jen čtyři hodnoty:
a := [1,2,3,10] b := [1,2,3,4,5,6,7,8] for i { println(a[i]*b[i]) } 1 4 9 40
Naproti tomu pokud výraz otočíme, dojde k chybě, protože druhé pole ve výrazu je kratší než pole první:
a := [1,2,3,10] b := [1,2,3,4,5,6,7,8] for i { println(b[i]*a[i]) } --- ERROR --- main (src/main.dyon) consise_loops (src/main.dyon) Out of bounds `4` 219,24: println(b[i]*a[i]) 219,24: ^
14. Zkrácený zápis vnořených smyček
V případě, že máme vytvořené dvourozměrné pole:
x:= [[1,2,3], [4,5,6], [7,8,9]]
A potřebujeme procházet všemi jeho prvky, je možné použít zkrácený zápis popsaný v předchozí kapitole:
for i { for j { println(x[i][j]) } }
Dyon však umožňuje další zkrácení vnořené smyčky, a to následovně:
for i, j { println(x[i][j]) }
Totéž samozřejmě platí pro trojrozměrná, čtyřrozměrná atd. pole:
y:= [[[1,2,3], [4,5,6], [7,8,9]], [[1,0,0], [0,1,0], [0,0,1]]] for i { for j { for k { println(y[i][j][k]) } } }
Versus:
y:= [[[1,2,3], [4,5,6], [7,8,9]], [[1,0,0], [0,1,0], [0,0,1]]] for i, j, k { println(y[i][j][k])
15. Zápis často používaných typů smyček – suma, hledání maxima atd.
Pro často používané smyčky, například pro nalezení minima, maxima, výpočet sumy prvků, součet 2D/3D/4D vektorů apod. obsahuje jazyk Dyon specializované konstrukce, především:
Konstrukce | Alternativní zápis | Význam |
---|---|---|
min | zjištění minima | |
max | zjištění maxima | |
any | ∃ | test, zda je výraz pravdivý alespoň pro jeden prvek |
all | ∀ | test, zda je výraz pravdivý pro všechny prvky |
sum | ∑ | suma prvků |
prod | ∏ | výsledek vynásobení všech prvků |
Podívejme se na některé ukázky:
a := [3,2,1,10,1] minimum := min i { a[i] } println(minimum) maximum := max i { a[i] } println(maximum) suma := sum i len(a) { a[i] } println(suma) product := prod i len(a) { a[i] } println(product)
S výsledky:
1 10 17 60
16. Repositář s demonstračními příklady
Většina ukázek z předchozích kapitol byla přidána do dvou demonstračních příkladů, které byly uloženy do Git repositáře dostupného na adrese https://github.com/tisnik/presentations. Demonstrační příklady si můžete v případě potřeby stáhnout i jednotlivě bez nutnosti klonovat celý repositář (ovšem u projektů je lepší mít celý repositář, abyste nemuseli pracně stahovat všechny potřebné soubory):
17. Odkazy na Internetu
- Dyon: tutoriál
http://www.piston.rs/dyon-tutorial/ - Repositář s programovacím jazykem Dyon
https://github.com/PistonDevelopers/dyon - Dyon: A rusty dynamically typed scripting language
https://rust.libhunt.com/project/dyon - Dyon snippets
https://github.com/PistonDevelopers/dyon_snippets - Scripting without garbage collector
http://blog.piston.rs/2016/02/21/scripting-without-garbage-collector/ - Podpora pro „matematické“ smyčky
https://github.com/PistonDevelopers/dyon/issues/119 - Rust-clippy Wiki
https://github.com/rust-lang-nursery/rust-clippy/wiki - Rust-clippy
https://rust.libhunt.com/project/rust-clippy - ndarray – dokumentace k modulu
https://bluss.github.io/rust-ndarray/master/ndarray/index.html - ndarray – Crate
https://crates.io/crates/ndarray - rustup
https://www.rustup.rs/ - rustup: the Rust toolchain installer (Git repositář + dokumentace)
https://github.com/rust-lang-nursery/rustup.rs - The Rust FFI Omnibus
http://jakegoulding.com/rust-ffi-omnibus/ - Build Script Support
http://doc.crates.io/build-script.html - Calling Rust From Python
https://bheisler.github.io/post/calling-rust-in-python/ - Calling Rust in Python (komentáře k předchozímu článku)
https://www.reddit.com/r/rust/comments/63iy5a/calling_rust_in_python/ - CFFI Documentation
https://cffi.readthedocs.io/en/latest/ - Build Script Support
http://doc.crates.io/build-script.html - Creating a shared and static library with the gnu compiler [gcc]
http://www.adp-gmbh.ch/cpp/gcc/create_lib.html - ctypes — A foreign function library for Python
https://docs.python.org/2/library/ctypes.html - FFI: Foreign Function Interface
https://doc.rust-lang.org/book/ffi.html - Primitive Type pointer
https://doc.rust-lang.org/std/primitive.pointer.html - Cargo: správce projektů a balíčků pro programovací jazyk Rust
https://mojefedora.cz/cargo-spravce-projektu-a-balicku-pro-programovaci-jazyk-rust/ - Network Communication and Serialization in Rust
https://www.safaribooksonline.com/blog/2014/01/28/network-communication-serialization-rust/ - Crate bincode
http://tyoverby.com/bincode/bincode/index.html - Struct std::fs::File
https://doc.rust-lang.org/std/fs/struct.File.html - Trait std::io::Seek
https://doc.rust-lang.org/std/io/trait.Seek.html - Trait std::io::Read
https://doc.rust-lang.org/std/io/trait.Read.html - Trait std::io::Write
https://doc.rust-lang.org/std/io/trait.Write.html - Trait std::io::BufRead
https://doc.rust-lang.org/std/io/trait.BufRead.html - Module std::io::prelude
https://doc.rust-lang.org/std/io/prelude/index.html - std::net::IpAddr
https://doc.rust-lang.org/std/net/enum.IpAddr.html - std::net::Ipv4Addr
https://doc.rust-lang.org/std/net/struct.Ipv4Addr.html - std::net::Ipv6Addr
https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html - TcpListener
https://doc.rust-lang.org/std/net/struct.TcpListener.html - TcpStream
https://doc.rust-lang.org/std/net/struct.TcpStream.html - Binary heap (Wikipedia)
https://en.wikipedia.org/wiki/Binary_heap - Binární halda (Wikipedia)
https://cs.wikipedia.org/wiki/Bin%C3%A1rn%C3%AD_halda - Halda (datová struktura)
https://cs.wikipedia.org/wiki/Halda_%28datov%C3%A1_struktura%29 - Struct std::collections::HashSet
https://doc.rust-lang.org/std/collections/struct.HashSet.html - Struct std::collections::BTreeSet
https://doc.rust-lang.org/std/collections/struct.BTreeSet.html - Struct std::collections::BinaryHeap
https://doc.rust-lang.org/std/collections/struct.BinaryHeap.html - Set (abstract data type)
https://en.wikipedia.org/wiki/Set_%28abstract_data_type%29#Language_support - Associative array
https://en.wikipedia.org/wiki/Associative_array - Hash Table
https://en.wikipedia.org/wiki/Hash_table - B-tree
https://en.wikipedia.org/wiki/B-tree - Pedro Celis: Robin Hood Hashing (naskenované PDF!)
https://cs.uwaterloo.ca/research/tr/1986/CS-86–14.pdf - Robin Hood hashing
http://codecapsule.com/2013/11/11/robin-hood-hashing/ - Robin Hood hashing: backward shift deletion
http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/ - Module std::collections
https://doc.rust-lang.org/std/collections/ - Module std::vec
https://doc.rust-lang.org/nightly/std/vec/index.html - Struct std::collections::VecDeque
https://doc.rust-lang.org/std/collections/struct.VecDeque.html - Struct std::collections::LinkedList
https://doc.rust-lang.org/std/collections/struct.LinkedList.html - Module std::fmt
https://doc.rust-lang.org/std/fmt/ - Macro std::println
https://doc.rust-lang.org/std/macro.println.html - Enum std::result::Result
https://doc.rust-lang.org/std/result/enum.Result.html - Module std::result
https://doc.rust-lang.org/std/result/ - Result
http://rustbyexample.com/std/result.html - Rust stdlib: Option
https://doc.rust-lang.org/std/option/enum.Option.html - Module std::option
https://doc.rust-lang.org/std/option/index.html - Rust by example: option
http://rustbyexample.com/std/option.html - Rust by example: if-let
http://rustbyexample.com/flow_control/if_let.html - Rust by example: while let
http://rustbyexample.com/flow_control/while_let.html - Rust by example: Option<i32>
http://rustbyexample.com/std/option.html - An Overview of Macros in Rust
http://words.steveklabnik.com/an-overview-of-macros-in-rust - A Practical Intro to Macros in Rust 1.0
https://danielkeep.github.io/practical-intro-to-macros.html - The Rust Programming Language: macros
https://doc.rust-lang.org/beta/book/macros.html - Rust by example: 15 macro_rules!
http://rustbyexample.com/macros.html - Primitive Type isize
https://doc.rust-lang.org/nightly/std/primitive.isize.html - Primitive Type usize
https://doc.rust-lang.org/nightly/std/primitive.usize.html - Primitive Type array
https://doc.rust-lang.org/nightly/std/primitive.array.html - Module std::slice
https://doc.rust-lang.org/nightly/std/slice/ - Rust by Example: 2.3 Arrays and Slices
http://rustbyexample.com/primitives/array.html - What is the difference between Slice and Array (stackoverflow)
http://stackoverflow.com/questions/30794235/what-is-the-difference-between-slice-and-array - Learning Rust With Entirely Too Many Linked Lists
http://cglab.ca/~abeinges/blah/too-many-lists/book/ - Testcase: linked list
http://rustbyexample.com/custom_types/enum/testcase_linked_list.html - Operators and Overloading
https://doc.rust-lang.org/book/operators-and-overloading.html - Module std::ops
https://doc.rust-lang.org/std/ops/index.html - Module std::cmp
https://doc.rust-lang.org/std/cmp/index.html - Trait std::ops::Add
https://doc.rust-lang.org/stable/std/ops/trait.Add.html - Trait std::ops::AddAssign
https://doc.rust-lang.org/std/ops/trait.AddAssign.html - Trait std::ops::Drop
https://doc.rust-lang.org/std/ops/trait.Drop.html - Trait std::cmp::Eq
https://doc.rust-lang.org/std/cmp/trait.Eq.html - Struct std::boxed::Box
https://doc.rust-lang.org/std/boxed/struct.Box.html - Explore the ownership system in Rust
https://nercury.github.io/rust/guide/2015/01/19/ownership.html - Rust's ownership and move semantic
http://www.slideshare.net/saneyuki/rusts-ownership-and-move-semantics - Trait std::marker::Copy
https://doc.rust-lang.org/stable/std/marker/trait.Copy.html - Trait std::clone::Clone
https://doc.rust-lang.org/stable/std/clone/trait.Clone.html - The Stack and the Heap
https://doc.rust-lang.org/book/the-stack-and-the-heap.html - Rust Compare: Pointers & References
http://www.rust-compare.com/site/pointers.html - Rust Compare: Parameters
http://www.rust-compare.com/site/params.html - Why does this compile? Automatic dereferencing?
https://users.rust-lang.org/t/why-does-this-compile-automatic-dereferencing/2183 - Understanding Pointers, Ownership, and Lifetimes in Rust
http://koerbitz.me/posts/Understanding-Pointers-Ownership-and-Lifetimes-in-Rust.html - Rust lang series episode #25 — pointers (#rust-series)
https://steemit.com/rust-series/@jimmco/rust-lang-series-episode-25-pointers-rust-series - Rust – home page
https://www.rust-lang.org/en-US/ - Rust – Frequently Asked Questions
https://www.rust-lang.org/en-US/faq.html - Destructuring and Pattern Matching
https://pzol.github.io/getting_rusty/posts/20140417_destructuring_in_rust/ - The Rust Programming Language
https://doc.rust-lang.org/book/ - Rust (programming language)
https://en.wikipedia.org/wiki/Rust_%28programming_language%29 - Go – home page
https://golang.org/ - Stack Overflow – Most Loved, Dreaded, and Wanted language
https://stackoverflow.com/research/developer-survey-2016#technology-most-loved-dreaded-and-wanted - Rust vs Go (dva roky staré hodnocení, od té doby došlo k posunům v obou jazycích)
http://jaredforsyth.com/2014/03/22/rust-vs-go/ - Rust vs Go: My experience
https://www.reddit.com/r/golang/comments/21m6jq/rust_vs_go_my_experience/ - Friends of Rust (Organizations running Rust in production)
https://www.rust-lang.org/en-US/friends.html - Rust programs versus C++ g++
https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=rust&lang2=gpp - Další benchmarky (nejedná se o reálné příklady „ze života“)
https://github.com/kostya/benchmarks - Go na Redditu
https://www.reddit.com/r/golang/ - Rust vs. Go
http://vschart.com/compare/rust/vs/go-language - Abstraction without overhead: traits in Rust
https://blog.rust-lang.org/2015/05/11/traits.html - Method Syntax
https://doc.rust-lang.org/book/method-syntax.html - Traits in Rust
https://doc.rust-lang.org/book/traits.html - Functional Programming in Rust – Part 1 : Function Abstraction
http://blog.madhukaraphatak.com/functional-programming-in-rust-part-1/ - Of the emerging systems languages Rust, D, Go and Nim, which is the strongest language and why?
https://www.quora.com/Of-the-emerging-systems-languages-Rust-D-Go-and-Nim-which-is-the-strongest-language-and-why - Chytré ukazatele (moderní verze jazyka C++) [MSDN]
https://msdn.microsoft.com/cs-cz/library/hh279674.aspx - UTF-8 Everywhere
http://utf8everywhere.org/ - Rust by Example
http://rustbyexample.com/ - Rust oficiálně ve Fedoře
https://mojefedora.cz/rust-oficialne-ve-fedore/ - Resource acquisition is initialization
https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization - TIOBE index (October 2016)
http://www.tiobe.com/tiobe-index/ - Porovnání Go, D a Rustu na OpenHubu:
https://www.openhub.net/languages/compare?language_name[]=-1&language_name[]=-1&language_name[]=dmd&language_name[]=golang&language_name[]=rust&language_name[]=-1&measure=commits - String Types in Rust
http://www.suspectsemantics.com/blog/2016/03/27/string-types-in-rust/ - Trait (computer programming)
https://en.wikipedia.org/wiki/Trait_%28computer_programming%29 - Type inference
https://en.wikipedia.org/wiki/Type_inference