Obsah
1. Incanter: prostředí pro statistické výpočty s grafickým výstupem založené na Clojure
2. Proč Incanter vznikl a z jakého důvodu by nás mohl zajímat?
3. Nový programovací jazyk či „pouhá“ knihovna?
4. Instalace projektu Incanter
5. První spuštění interaktivního prostředí projektu Incanter
6. Infixová notace v lispovském jazyku aneb síla makrosystému jazyka Clojure
7. Matice jakožto základní datová struktura, s níž Incanter pracuje
8. Základní informace o knihovně core.matrix
10. Vytvoření matice ze sekvence
11. Matice jako sekvence řádků
12. Základní operace s maticemi
15. Jednoduché grafy s průběhy funkcí
16. Zápis vzorců způsobem převzatým z LaTeXu
17. Uložení grafů do rastrových obrázků i do vektorového výkresu
18. Repositář s demonstračními příklady
19. Předchozí články o programovacím jazyku Clojure a jeho knihovnách
1. Incanter: prostředí pro statistické výpočty s grafickým výstupem založené na Clojure
Na stránce www.clojure-toolbox.com, na níž se nachází nejužitečnější a samozřejmě taktéž nejpopulárnější knihovny a nástroje určené pro programovací jazyk Clojure, popř. pro ClojureScript, nalezneme mj. i nástroj nazvaný Incanter. Jedná se o skupinu knihoven pro Clojure, jejichž cílem je vytvořit rychlejší a rozšiřitelnější alternativu k nástroji a programovacímu jazyku R, který se používá v oblasti statistických výpočtů, vizualizace dat apod. Základní informace o nepochybně zajímavém projektu Incanter získáte ze slajdů prezentace Data Sorcery with Clojure & Incanter. V krátkém seriálu, který dnes (tímto článkem) začíná na Rootu vycházet, se postupně seznámíme jak se základními postupy, tak i se složitějšími příklady použití Incanteru (datové zdroje, kombinované grafy apod.)

Obrázek 1: Logo projektu Incanter.
Nástroj Incanter svým uživatelům nabízí zejména tyto funkce:
- Statistické funkce (nejenom ty základní, ale i poměrně pokročilé).
- Matematické funkce pro práci s vektory a maticemi.
- Podporu pro tvorbu různých typů grafů a pro vizualizaci dat.
- Export grafů do rastrových formátů popř. do vektorového formátu SVG.
- Funkce pro manipulaci s daty a s datovými zdroji (mj. i z Excelu atd.).
- Základní symbolické výpočty (prozatím je podporována symbolická derivace).

Obrázek 2: Snímek z videa.
2. Proč Incanter vznikl a z jakého důvodu by nás mohl zajímat?
Zajímavé a možná i poučné bude zjistit, z jakého důvodu vlastně projekt Incanter vznikl a proč by pro nás mohl být zajímavý, resp. proč použít Incanter a nikoli R, jazyk Julia či řešení založené na Pythonu). Hlavní motivací autorů tohoto projektu bylo vytvoření rozšiřitelné platformy určené pro statistické výpočty s umožněním vizualizace výsledků pomocí různých typů grafů. Tato platforma by měla uživatelům nabízet stejné či lepší vyjadřovací schopnosti než projekt R, ovšem s tím, že Incanter využije všech výhod aplikace běžící na virtuálním stroji Javy (JVM). Důvodem, proč je – minimálně slovy autorů – JVM vhodnou platformou, je mj. i to, že pro ni existuje prakticky nepřeberné množství knihoven určených pro načítání dat (použita je například knihovna xls), zpracování dat, jejich konverzi, prezentaci, přístupu k různým databázím (relační, dokumentové, objektové) atd. (ostatně přímo Incanter používá rozhraní k MongoDB pro serializaci svých datových struktur).

Obrázek 3: Incanter je alternativou ke známému nástroji R.
Nevýhodou běhu nad JVM oproti nativnímu kódu (ne oproti interpretu R!) jsou samozřejmě pomalejší výpočty, což se může negativně projevit při zpracování rozsáhlejších dat (nicméně zrovna v oblasti práce s homogenními maticemi je zpomalení přibližně „jen“ 10–20% oproti optimalizovanému Fortranu – výsledky benchmarků si uvedeme příště). Na druhou stranu je možné pro JVM použít například knihovnu Parallel Colt, která umožňuje některé výpočty provádět nativním kódem (BLAS, LAPACK, ARPACK, ATLAS atd.). Právě tato knihovna je v případě potřeby používána i systémem Incanter.

Obrázek 4: V případě, že budete potřebovat použít jazyk R nad JVM, může vám pomoci projekt renjin (prozatím jsem nezkoušel, takže jen informuji o jeho existenci).
3. Nový programovací jazyk či „pouhá“ knihovna?
Po volbě platformy se autoři Incanteru zaměřili na další problém – jak vlastně uživatelům umožnit používat statistické funkce popř. funkce pro vykreslování grafů? V případě projektu R byl zvolen vlastní programovací jazyk s poměrně velkými vyjadřovacími schopnostmi, který navíc uživatele odstiňuje od nízkoúrovňových operací. V případ Incanteru je tomu jinak, protože se vlastně jedná o „pouhou“ knihovnu naprogramovanou v jazyku Clojure. Ovšem Clojure, jakožto homoikonický jazyk s podporou maker, může posloužit pro tvorbu DSL (doménově specifických jazyků), což znamená, že nad čistým Clojure si uživatelé mohou postavit další vrstvu a tu používat. Současně jim ovšem Clojure nabízí již výše zmíněnou možnost použití libovolné knihovny, která pro JVM vznikla (díky Java interop). Velká flexibilita Clojure je ostatně jedním z důvodů, proč není Incanter určen přímo pro Javu jakožto primárního jazyka pro JVM.

Obrázek 5: Incanter používá mj. i známou a užitečnou knihovnu JFreeChart.
Navíc volba lispovského jazyka, kterým Clojure i přes některé rozdíly nepochybně je, není pro oblast statistických výpočtů zcela nesmyslná, protože stále ještě existuje početná komunita používající dnes již vlastně prastarý systém Lisp-Stat (známý též jako XLispStat) popř. nástroje nad ním postavené, například program ViSTa nebo ARC. XLispStat, který měl velký vliv na celý obor vizualizací statistických dat, se používal a – což je zajímavé – stále ještě používá například v oblasti GIS, epidemiologie, astronomie atd. (to je ostatně velmi poučné – některé obory mohou být v oblasti IT resp. používaných nástrojů hodně konzervativní). A právě pro tuto komunitu může být projekt Incanter užitečný. Ostatně i samotný jazyk R byl Lispem ovlivněn, zejména ve svých počátcích.
4. Instalace projektu Incanter
Na stránkách projektu Incanter nalezneme Java Archiv (jar), který obsahuje všechny potřebné knihovny a pro svou činnost vyžaduje pouze přítomnost JRE (Java Runtime Environment). Problém je, že tento archiv je založen na dnes již notně zastaralé verzi Incanteru, takže bude lepší si provést překlad a instalaci verze vlastní. Budete potřebovat Clojure (aspoň verze 1.7) a taktéž nástroj Leiningen; všechny další knihovny a nástroje se stáhnou automaticky při překladu.
Nejdříve naklonujeme celý repositář:
$ git clone https://github.com/incanter/incanter Cloning into 'incanter'... remote: Enumerating objects: 13863, done. remote: Total 13863 (delta 0), reused 0 (delta 0), pack-reused 13863 Receiving objects: 100% (13863/13863), 41.45 MiB | 4.19 MiB/s, done. Resolving deltas: 100% (8228/8228), done. Checking connectivity... done.
Přejdeme do vytvořeného podadresáře:
cd incanter/
V případě některých verzí JVM je nutné nastavit proměnnou prostředí LEIN_JVM_OPTS tak, jak je to popsáno zde. Toto nastavení zajistí, že nástroj Leiningen bude schopen stáhnout všechny potřebné balíčky:
$ export LEIN_JVM_OPTS=-Dhttps.protocols=TLSv1.2
Následuje vlastní překlad, v jehož rámci se stáhnou potřebné knihovny a uloží se do podadresáře ~/.m2:
$ lein sub install Reading project from modules/incanter-core Retrieving org/clojure/spec.alpha/0.1.143/spec.alpha-0.1.143.pom from central ... ... ... Retrieving swingrepl/swingrepl/1.3.0/swingrepl-1.3.0.jar from clojars Created /home/tester/temp/out/xxx/incanter/./target/incanter-1.9.4-SNAPSHOT.jar Wrote /home/tester/temp/out/xxx/incanter/./pom.xml Installed jar and pom into local repo.
5. První spuštění interaktivního prostředí projektu Incanter
Incanter používá, podobně jako další projekty se stejným zaměřením, vlastní interaktivní smyčku REPL. Tu spustíme přímo z adresáře, kam byl naklonován repositář projektu:
$ cd incanter/
Nyní již můžeme interaktivní smyčku REPL spustit:
$ lein repl
Měla by se vypsat klasická uvítací obrazovka REPLu jazyka Clojure:
nREPL server started on port 52443 on host 127.0.0.1 - nrepl://127.0.0.1:52443 REPL-y 0.3.5, nREPL 0.2.6 Clojure 1.8.0 OpenJDK 64-Bit Server VM 1.7.0_79-b14 Docs: (doc function-name-here) (find-doc "part-of-name-here") Source: (source function-name-here) Javadoc: (javadoc java-object-or-class-here) Exit: Control+D or (exit) or (quit) Results: Stored in vars *1, *2, *3, an exception in *e
Dále můžeme otestovat, jestli jsou na CLASSPATH umístěny všechny důležité knihovny Incanteru:
(use '(incanter core stats charts)) nil
Pokud se skutečně vypíše pouze nil, znamená to, že knihovny je možné použít. Zkusme si tedy vykreslit například histogram náhodných hodnot s normálním rozložením:
(view (histogram (sample-normal 1000)))

Obrázek 6: Histogram náhodných hodnot s normálním rozložením.
Parametry histogramu jsou samozřejmě plně konfigurovatelné. Podrobnosti si řekneme příště:
(view (histogram (sample-normal 100000) :nbins 50 :title "Normální rozložení" :legend true :y-label "Četnost"))

Obrázek 7: Upravený histogram.
6. Infixová notace v lispovském jazyku aneb síla makrosystému jazyka Clojure
Incanter je sice knihovna (resp. skupina knihoven) určená pro programovací jazyk Clojure, který je založen na lispovské syntaxi volání funkcí, ovšem díky existenci makra $= je možné výrazy zapisovat i v infixové podobě, a to včetně správného vyhodnocení priorit operátorů. Podívejme se na několik příkladů.
Základní aritmetické operátory s vyhodnocením priorit:
incanter.irepl=> ($= 1 + 2) 3 incanter.irepl=> ($= 1 + 2 * 3) 7
Operátor pro umocnění se zapisuje pomocí dvojice hvězdiček:
incanter.irepl=> ($= 2 ** 10) 1024.0 incanter.irepl=> ($= 2 ** -4)) 0.0625
Clojure se snaží při dělení celých čísel vyjádřit výsledek formou zlomku:
incanter.irepl=> ($= 10 + 20 * (4 - 5) / 6) 20/3
Zpracovat lze dokonce i vektory a matice (operátory jsou přetížené):
incanter.irepl=> ($= [1 2 3] + [4 5 6]) [5 7 9] incanter.irepl=> ($= [1 2 3] * [4 5 6]) [4 10 18] incanter.irepl=> ($= [[1 2][3 4]] + [[5 6][7 8]]) [[6 8] [10 12]]
Využití broadcastingu popsaného dále:
incanter.irepl=> ($= [1 2 3] + 10) [11 12 13] incanter.irepl=> ($= [1 2 3] * -1) [-1 -2 -3]
Výsledky jsou typu:
incanter.irepl=> (type ($= [[1 2][3 4]] + [[5 6][7 8]])) clojure.lang.PersistentVector incanter.irepl=> (type ($= [1 2 3] * -1)) clojure.lang.PersistentVector
7. Matice jakožto základní datová struktura, s níž Incanter pracuje
Projekt Incanter je založen na zpracování (rozsáhlých) matic a tzv. datasetů. Ve skutečnosti však klasicky chápané matice v Clojure příliš podporovány nejsou. Při studiu základních knihoven Clojure lze dojít k závěru, že vlastně jen velmi málo funkcí a maker je určeno pro práci s těmito datovými typy, i když je samozřejmě možné jak vektory, tak i matice velmi snadno reprezentovat s využitím základních sekvenčních datových struktur Clojure – seznamů a vektorů. Ve skutečnosti to však není zcela ideální řešení, a to hned z několika důvodů, jejichž společným rysem je rychlost prováděných operací. Z tohoto důvodu je v případě implementace algoritmů, v nichž se intenzivně používají operace s maticemi, mnohem výhodnější využít možností specializovaných knihoven. My se dnes seznámíme především s elegantně navrženou knihovnou core.matrix, protože ta je používána i projektem Incanter.
V přednášce nazvané velmi příhodně „Enter the Matrix“, která je dostupná na adrese http://www.slideshare.net/mikeranderson/2013–1114-enter-thematrix, je mj. ukázáno, jakým způsobem jsou v Clojure implementována různá paradigmata programování. Díky podpoře maker a způsobu zápisu programového kódu v Clojure lze velmi snadno implementovat různé doménově specifické jazyky (DSL), mj. i právě jazyk pro array programming:
Paradigma | Jazyk | Implementace v Clojure |
---|---|---|
funkcionální | Haskell | clojure.core |
OOP | Smalltalk | clojure.core |
metaprogramování | Lisp | clojure.core |
logické | Prolog | core.logic |
array programming | APL, J | core.matrix |
8. Základní informace o knihovně core.matrix
Knihovna nazvaná core.matrix je určená těm vývojářům, kteří ve svých projektech potřebují provádět velké množství operací s maticemi různých dimenzí, a to na poměrně vysoké úrovni, tj. bez nutnosti přesně specifikovat, jak mají být matice uloženy v paměti, jakým způsobem provádět operaci násobení matic atd. Díky tomuto přístupu a taktéž díky vlastnostem programovacího jazyka Clojure (existence tzv. threading makra a funkcí vyššího řádu) se práce s maticemi do značné míry začíná podobat práci v APL, až na ten rozdíl, že algoritmy zapisované v Clojure jsou pro většinu vývojářů přece jen čitelnější :-). Taktéž je důležité, že rozhraní definované v knihovně core.matrix může mít několik implementací. V současnosti se jedná o vectorz-clj, Clatrix a NDArray. V core.matrix navíc došlo k rozšíření operátorů +, – atd. takovým způsobem, že je lze použít i pro zpracování vektorů a matic (ve skutečnosti se samozřejmě nejedná o skutečné operátory, protože tento koncept Clojure nepotřebuje).
9. Konstruktory matic
Skutečný vektor či matice se vytvoří konstruktorem matrix. Povšimněte si, že tomuto konstruktoru můžete předat klasický vektor programovacího jazyka Clojure; samozřejmě lze předat i vektor vektorů:
incanter.irepl=> (matrix [[1 2] [4 5]]) #vectorz/matrix [[1.0,2.0], [4.0,5.0]] incanter.irepl=> (matrix [1 2 3]) #vectorz/vector [1.0,2.0,3.0]
Dalším způsobem konstrukce matice je určení hodnoty všech prvků; za touto hodnotou následuje určení rozměrů matice:
incanter.irepl=> (matrix 0 10 10) #vectorz/matrix [[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]]
Povšimněte si, že i zlomky se automaticky převádí na typ float:
incanter.irepl=> (matrix 1/2 5 5) #vectorz/matrix [[0.5,0.5,0.5,0.5,0.5], [0.5,0.5,0.5,0.5,0.5], [0.5,0.5,0.5,0.5,0.5], [0.5,0.5,0.5,0.5,0.5], [0.5,0.5,0.5,0.5,0.5]]
Nejdříve se zadává počet řádků, poté počet sloupců:
incanter.irepl=> (matrix 1 3 5) #vectorz/matrix [[1.0,1.0,1.0,1.0,1.0], [1.0,1.0,1.0,1.0,1.0], [1.0,1.0,1.0,1.0,1.0]]
incanter.irepl=> (matrix 1 8 3) #vectorz/matrix [[1.0,1.0,1.0], [1.0,1.0,1.0], [1.0,1.0,1.0], [1.0,1.0,1.0], [1.0,1.0,1.0], [1.0,1.0,1.0], [1.0,1.0,1.0], [1.0,1.0,1.0]]
10. Vytvoření matice ze sekvence
Vytvoření dvourozměrné matice výčtem prvků již známe:
incanter.irepl=> (matrix [[1 2 3] [4 5 6] [7 8 9]]) #vectorz/matrix [[1.0,2.0,3.0], [4.0,5.0,6.0], [7.0,8.0,9.0]]
Alternativně je možné prvky specifikovat v jednorozměrném vektoru a pouze přidat informaci o tom, jaké má matice rozměry:
incanter.irepl=> (matrix [1 2 3 4 5 6 7 8 9] 3) #vectorz/matrix [[1.0,2.0,3.0], [4.0,5.0,6.0], [7.0,8.0,9.0]]
Přebytečné prvky, které netvoří obdélníkovou matici, se nepoužijí:
incanter.irepl=> (matrix [1 2 3 4 5 6 7 8 9] 2) #vectorz/matrix [[1.0,2.0], [3.0,4.0], [5.0,6.0], [7.0,8.0]]
Kromě vektoru je samozřejmě použít libovolnou sekvenci podporovanou programovacím jazykem Clojure, takže matici 3×3 prvky můžeme vytvořit i takto:
incanter.irepl=> (matrix (range 1 10) 3) #vectorz/matrix [[1.0,2.0,3.0], [4.0,5.0,6.0], [7.0,8.0,9.0]]
Sloupcový vektor se vytvoří stejně snadno:
incanter.irepl=> (matrix (range 1 10) 1) #vectorz/matrix [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0], [7.0], [8.0], [9.0]]
Samozřejmě je možné použít i složitější zápisy – zde se žádná omezení nekladou:
incanter.irepl=> (matrix (map #(* 2 %) (take 25 (range))) 5) #vectorz/matrix [[0.0,2.0,4.0,6.0,8.0], [10.0,12.0,14.0,16.0,18.0], [20.0,22.0,24.0,26.0,28.0], [30.0,32.0,34.0,36.0,38.0], [40.0,42.0,44.0,46.0,48.0]]
11. Matice jako sekvence řádků
Z pohledu jazyka Clojure lze matici zpracovávat jako sekvenci jednotlivých řádků, což je poměrně užitečná vlastnost. Nejprve si vytvořme matici o rozměrech 3×3 prvky:
incanter.irepl=> (def M (matrix (range 1 10) 3)) #'incanter.irepl/M
Kontrola obsahu matice:
incanter.irepl=> M #vectorz/matrix [[1.0,2.0,3.0], [4.0,5.0,6.0], [7.0,8.0,9.0]]
Dále můžeme získat první řádek matice, a to běžnou funkcí first:
incanter.irepl=> (first M) #vectorz/vector [1.0,2.0,3.0]
Získání všech řádků kromě řádku prvního:
incanter.irepl=> (rest M) (#vectorz/vector [4.0,5.0,6.0] #vectorz/vector [7.0,8.0,9.0])
Díky tomu, že v základní knihovně jazyka Clojure nalezneme velké množství funkcí a maker pro zpracování sekvencí, lze například snadno sečíst všechny hodnoty v jednotlivých sloupcích matice:
incanter.irepl=> (reduce plus M) #vectorz/vector [12.0,15.0,18.0]
Popř. si naopak můžeme vyčíslit součty prvků na jednotlivých řádcích:
incanter.irepl=> (map sum M) (6.0 15.0 24.0)
Poznámka: povšimněte si, že se pokaždé vrátil jiný datový typ. Z tohoto důvodu je lepší při práci s maticemi používat operace popsané níže.
Další operace (pravděpodobně ne příliš užitečné):
incanter.irepl=> (map first M) (1.0 4.0 7.0) incanter.irepl=> (map second M) (2.0 5.0 8.0)
12. Základní operace s maticemi
Podívejme se nyní na některé základní operace s maticemi. Tomuto tématu bude věnován samostatný článek, ale krátkou ukázku si můžeme předvést již dnes. Nejdříve si opět vytvoříme matici:
incanter.irepl=> (def A (matrix [[1 2 3] #_=> [4 5 6] #_=> [7 8 9]])) #'incanter.irepl/A
Broadcasting umožňuje převést číslo na matici stejného řádu, jakou má druhý operand:
incanter.irepl=> ($= A + 2) #vectorz/matrix [[3.0,4.0,5.0], [6.0,7.0,8.0], [9.0,10.0,11.0]]
Vynásobení matice konstantou (skalárem):
incanter.irepl=> ($= A * -1) #vectorz/matrix [[-1.0,-2.0,-3.0], [-4.0,-5.0,-6.0], [-7.0,-8.0,-9.0]]
Vynásobení matice a vektoru, který byl opět rozšířen na matici:
incanter.irepl=> ($= A * [5 0 5]) #vectorz/matrix [[5.0,0.0,15.0], [20.0,0.0,30.0], [35.0,0.0,45.0]]
Skutečný „maticový“ součin matice a vektoru:
incanter.irepl=> (mmult A [5 0 0]) #vectorz/vector [5.0,20.0,35.0]
Matici můžeme transponovat:
incanter.irepl=> (trans A) #vectorz/matrix [[1.0,4.0,7.0], [2.0,5.0,8.0], [3.0,6.0,9.0]]
Můžeme provést vynásobení původní matice s maticí transponovanou:
incanter.irepl=> (mmult A (trans A)) #vectorz/matrix [[14.0,32.0,50.0], [32.0,77.0,122.0], [50.0,122.0,194.0]]
Další složitější varianta:
incanter.irepl=> (mmult A (trans A) A) #vectorz/matrix [[492.0,588.0,684.0], [1194.0,1425.0,1656.0], [1896.0,2262.0,2628.0]]
13. Výpočet inverzní matice
Výpočet inverzní matice zajišťuje funkce solve:
incanter.irepl=> (solve (matrix [[2 0 0] [0 2 0] [0 0 2]])) #vectorz/matrix [[0.5,0.0,0.0], [0.0,0.5,0.0], [0.0,0.0,0.5]]
Kontrola předchozího výpočtu:
incanter.irepl=> (mmult (solve (matrix [[2 0 0] [0 2 0] [0 0 2]])) (matrix [[2 0 0] [0 2 0] [0 0 2]])) #vectorz/matrix [[1.0,0.0,0.0], [0.0,1.0,0.0], [0.0,0.0,1.0]]
14. Symbolické výpočty
Knihovna Incanter sice v žádném případě nedokáže nahradit Mathematicu nebo Maple, ovšem obsahuje i modul pro symbolické výpočty, tj. (velmi zjednodušeně řečeno) pro úpravy výrazů a rovnic na základě manipulace se symboli a nikoli na základě numerických výpočtů. Prozatím je podporován především výpočet derivace podle zvolené proměnné. Ukažme si jednoduché příklady.
Načtení knihovny:
incanter.irepl=> (use '(incanter symbolic)) nil
Derivace funkce sinus podle proměnné x:
incanter.irepl=> (deriv (sin x) x) (cos x)
Složitější výraz s jedinou proměnnou:
incanter.irepl=> (deriv (cos (* x x)) x) (* (+ x x) (* -1 (sin (* x x))))
Další nepatrně složitější výraz:
incanter.irepl=> (deriv (+ (cos x) (tan x)) x) (+ (pow (cos x) -2) (* -1 (sin x)))
Derivace stejné funkce, ovšem pro rozdílné proměnné:
incanter.irepl=> (deriv (/ (+ (cos x) (tan y)) (ln z)) x) (+ (* (* (pow (* 1 (+ (cos x) (tan y)) (ln z))) -1) (* -1 (sin x))) (* (* -1 (deriv* (pow (* 1 (+ (cos x) (tan y)) (ln z))) x)) (+ (cos x) (tan y)))) incanter.irepl=> (deriv (/ (+ (cos x) (tan y)) (ln z)) y) (+ (* (* (pow (* 1 (+ (cos x) (tan y)) (ln z))) -1) (pow (cos y) -2)) (* (* -1 (deriv* (pow (* 1 (+ (cos x) (tan y)) (ln z))) y)) (+ (cos x) (tan y)))) incanter.irepl=> (deriv (/ (+ (cos x) (tan y)) (ln z)) z) (* (* -1 (deriv* (pow (* 1 (+ (cos x) (tan y)) (ln z))) z)) (+ (cos x) (tan y)))
15. Jednoduché grafy s průběhy funkcí
Nejjednodušším typem grafu je graf s průběhem zvolené funkce. Samotný graf se vytvoří pomocí function-plot, což je funkce vyššího řádu, které lze předat libovolnou jinou aritmetickou funkci a taktéž rozsah hodnot nezávislé proměnné. Výsledek lze zobrazit funkcí view. Nesmíte samozřejmě zapomenout na import knihovny charts:
(use '(incanter core charts)) (view (function-plot (fn [x] (sin x)) -10 10))

Obrázek 8: Graf s průběhem funkce sinus.
Osobně ovšem doporučuji jiný styl zápisu využívající threading makro:
(-> (fn [x] (sin x)) (function-plot -10 10) view)
Výsledkem bude naprosto stejný graf, jako v příkladu předchozím.
16. Zápis vzorců způsobem převzatým z LaTeXu
Jen v rychlosti (alespoň prozatím) si ukažme, jakým způsobem se do grafů přidávají vzorce zapsané a vysázené podobně, jako v LaTeXu. Používá se k tomu funkce add-latex, například:
(add-latex 0 250 "x^3 - 5x^2 + 3x +5")
Tato funkce přidá návěští přímo do grafu. Nesmíme samozřejmě zapomenout na importy:
(use '(incanter core charts latex))
Můžeme zde s výhodou použít standardní makro doto:
(doto (function-plot (fn [x] ($= x ** 3 - 5 * x ** 2 + 3 * x + 5)) -10 10) (add-latex 0 250 "x^3 - 5x^2 + 3x +5") view)

Obrázek 9: Výsledek předchozího příkazu.
17. Uložení grafů do rastrových obrázků i do vektorového výkresu
Kromě funkce view, která graf vykreslí do samostatného okna, ho můžeme uložit do rastrového souboru funkcí save. Například:
(ns png-output (:use (incanter core stats charts svg))) (save (histogram (sample-normal 1000)) "histogram1.png") (save (histogram (sample-normal 100000) :nbins 50 :title "Normální rozložení" :legend true :y-label "Četnost") "histogram2.png") (save (function-plot (fn [x] ($= x ** 3 - 5 * x ** 2 + 3 * x + 5)) -10 10) "funkce.png")
Někdy může být výhodnější použít export do vektorového formátu SVG:
(ns svg-output (:use (incanter core stats charts svg))) (save-svg (histogram (sample-normal 1000)) "histogram1.svg") (save-svg (histogram (sample-normal 100000) :nbins 50 :title "Normální rozložení" :legend true :y-label "Četnost") "histogram2.svg") (save-svg (function-plot (fn [x] ($= x ** 3 - 5 * x ** 2 + 3 * x + 5)) -10 10) "funkce.svg")
Podrobnosti si vysvětlíme příště.
18. Repositář s demonstračními příklady
Zdrojové kódy všech dnes popsaných demonstračních příkladů byly uloženy do Git repositáře dostupného na adrese https://github.com/tisnik/incanter-examples (stále na GitHubu :-). V případě, že nebudete chtít klonovat celý repositář (ten je ovšem stále velmi malý, dnes má doslova několik kilobajtů), můžete namísto toho použít odkazy na jednotlivé příklady, které naleznete v následující tabulce:
# | Demonstrační příklad | Popis | Cesta |
---|---|---|---|
1 | introduction.clj | otestování funkčnosti Incanteru | https://github.com/tisnik/incanter-examples/blob/master/incanter-1/introduction.clj |
2 | infix.clj | použití infix operátorů | https://github.com/tisnik/incanter-examples/blob/master/incanter-1/infix.clj |
3 | matrices.clj | práce s maticemi | https://github.com/tisnik/incanter-examples/blob/master/incanter-1/matrices.clj |
4 | png_output.clj | uložení grafu do PNG | https://github.com/tisnik/incanter-examples/blob/master/incanter-1/png_output.clj |
5 | svg_output.clj | uložení grafu do SVG | https://github.com/tisnik/incanter-examples/blob/master/incanter-1/svg_output.clj |
6 | heat_map.clj | tzv.„heat mapy“ | https://github.com/tisnik/incanter-examples/blob/master/incanter-1/heat_map.clj |
7 | parametric_plot.clj | jednoduchý parametrický graf | https://github.com/tisnik/incanter-examples/blob/master/incanter-1/parametric_plot.clj |
19. Předchozí články o programovacím jazyku Clojure a jeho knihovnách
- Clojure 1: Úvod
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm/ - Clojure 2: Symboly, kolekce atd.
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-2-cast/ - Clojure 3: Funkcionální programování
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-3-cast-funkcionalni-programovani/ - Clojure 4: Kolekce, sekvence a lazy sekvence
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-4-cast-kolekce-sekvence-a-lazy-sekvence/ - Clojure 5: Sekvence, lazy sekvence a paralelní programy
http://www.root.cz/clanky/clojure-a-bezpecne-aplikace-pro-jvm-sekvence-lazy-sekvence-a-paralelni-programy/ - Clojure 6: Podpora pro paralelní programování
http://www.root.cz/clanky/programovaci-jazyk-clojure-6-futures-nejsou-jen-financni-derivaty/ - Clojure 7: Další funkce pro paralelní programování
http://www.root.cz/clanky/programovaci-jazyk-clojure-7-dalsi-podpurne-prostredky-pro-paralelni-programovani/ - Clojure 8: Identity, stavy, neměnné hodnoty a reference
http://www.root.cz/clanky/programovaci-jazyk-clojure-8-identity-stavy-nemenne-hodnoty-a-referencni-typy/ - Clojure 9: Validátory, pozorovatelé a kooperace s Javou
http://www.root.cz/clanky/programovaci-jazyk-clojure-9-validatory-pozorovatele-a-kooperace-mezi-clojure-a-javou/ - Clojure 10: Kooperace mezi Clojure a Javou
http://www.root.cz/clanky/programovaci-jazyk-clojure-10-kooperace-mezi-clojure-a-javou-pokracovani/ - Clojure 11: Generátorová notace seznamu/list comprehension
http://www.root.cz/clanky/programovaci-jazyk-clojure-11-generatorova-notace-seznamu-list-comprehension/ - Clojure 12: Překlad programů z Clojure do bajtkódu JVM I:
http://www.root.cz/clanky/programovaci-jazyk-clojure-12-preklad-programu-z-clojure-do-bajtkodu-jvm/ - Clojure 13: Překlad programů z Clojure do bajtkódu JVM II:
http://www.root.cz/clanky/programovaci-jazyk-clojure-13-preklad-programu-z-clojure-do-bajtkodu-jvm-pokracovani/ - Clojure 14: Základy práce se systémem maker
http://www.root.cz/clanky/programovaci-jazyk-clojure-14-zaklady-prace-se-systemem-maker/ - Clojure 15: Tvorba uživatelských maker
http://www.root.cz/clanky/programovaci-jazyk-clojure-15-tvorba-uzivatelskych-maker/ - Clojure 16: Složitější uživatelská makra
http://www.root.cz/clanky/programovaci-jazyk-clojure-16-slozitejsi-uzivatelska-makra/ - Clojure 17: Využití standardních maker v praxi
http://www.root.cz/clanky/programovaci-jazyk-clojure-17-vyuziti-standardnich-maker-v-praxi/ - Clojure 18: Základní techniky optimalizace aplikací
http://www.root.cz/clanky/programovaci-jazyk-clojure-18-zakladni-techniky-optimalizace-aplikaci/ - Clojure 19: Vývojová prostředí pro Clojure
http://www.root.cz/clanky/programovaci-jazyk-clojure-19-vyvojova-prostredi-pro-clojure/ - Clojure 20: Vývojová prostředí pro Clojure (Vimu s REPL)
http://www.root.cz/clanky/programovaci-jazyk-clojure-20-vyvojova-prostredi-pro-clojure-integrace-vimu-s-repl/ - Clojure 21: ClojureScript aneb překlad Clojure do JS
http://www.root.cz/clanky/programovaci-jazyk-clojure-21-clojurescript-aneb-preklad-clojure-do-javascriptu/ - Leiningen: nástroj pro správu projektů napsaných v Clojure
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (2)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-2/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (3)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-3/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (4)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-4/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (5)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-5/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (6)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-6/ - Programovací jazyk Clojure a databáze (1.část)
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-databaze-1-cast/ - Pluginy pro Leiningen
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-pluginy-pro-leiningen/ - Programovací jazyk Clojure a knihovny pro práci s vektory a maticemi
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-knihovny-pro-praci-s-vektory-a-maticemi/ - Programovací jazyk Clojure a knihovny pro práci s vektory a maticemi (2)
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-knihovny-pro-praci-s-vektory-a-maticemi-2/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (2)
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk-2/ - Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure
http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure/ - Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure (2)
http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure-2/ - Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure (3)
http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure-3/ - Programovací jazyk Clojure a práce s Gitem
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-prace-s-gitem/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (dokončení)
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk-dokonceni/ - Pixie: lehký skriptovací jazyk s „kouzelnými“ schopnostmi
https://www.root.cz/clanky/pixie-lehky-skriptovaci-jazyk-s-kouzelnymi-schopnostmi/ - Programovací jazyk Pixie: funkce ze základní knihovny a použití FFI
https://www.root.cz/clanky/programovaci-jazyk-pixie-funkce-ze-zakladni-knihovny-a-pouziti-ffi/ - Novinky v Clojure verze 1.9.0
https://www.root.cz/clanky/novinky-v-clojure-verze-1–9–0/ - Validace dat s využitím knihovny spec v Clojure 1.9.0
https://www.root.cz/clanky/validace-dat-s-vyuzitim-knihovny-spec-v-clojure-1–9–0/ - Použití jazyka Gherkin při tvorbě testovacích scénářů pro aplikace psané v Clojure
https://www.root.cz/clanky/pouziti-jazyka-gherkin-pri-tvorbe-testovacich-scenaru-pro-aplikace-psane-v-nbsp-clojure/ - Použití jazyka Gherkin při tvorbě testovacích scénářů pro aplikace psané v Clojure (2)
https://www.root.cz/clanky/pouziti-jazyka-gherkin-pri-tvorbe-testovacich-scenaru-pro-aplikace-psane-v-nbsp-clojure-2/
20. Odkazy na Internetu
- Incanter is a Clojure-based, R-like platform for statistical computing and graphics.
http://incanter.org/ - Evolution of incanter (Gource Visualization)
https://www.youtube.com/watch?v=TVfL5nPELr4 - Questions tagged [incanter] (na Stack Overflow)
https://stackoverflow.com/questions/tagged/incanter?sort=active - Data Sorcery with Clojure
https://data-sorcery.org/contents/ - Back to the Future: Lisp as a Base for a Statistical Computing System
https://rd.springer.com/chapter/10.1007/978–3–7908–2084–3_2 - Incanter Cheat Sheet
http://incanter.org/docs/incanter-cheat-sheet.pdf - Back to the Future: Lisp as a Base for a Statistical Computing System (celá verze článku)
https://www.researchgate.net/publication/227019917_Back_to_the_Future_Lisp_as_a_Base_for_a_Statistical_Computing_System - Lisp-Stat Information
http://homepage.cs.uiowa.edu/~luke/xls/xlsinfo/ - Sample Plots in Incanter
https://github.com/incanter/incanter/wiki/Sample-Plots-in-Incanter#line - vectorz-clj
https://github.com/mikera/vectorz-clj - vectorz – Examples
https://github.com/mikera/vectorz-clj/wiki/Examples - Array Programming
https://en.wikipedia.org/wiki/Array_programming - Discovering Array Languages
http://archive.vector.org.uk/art10008110 - no stinking loops – Kalothi
http://www.nsl.com/ - Vector (obsahuje odkazy na články, knihy a blogy o programovacích jazycích APL, J a K)
http://www.vector.org.uk/ - Colt
http://dst.lbl.gov/ACSSoftware/colt/ - Parallel Colt: Open Source Libraries for High Performance Scientific and Technical Computing in Java
http://incanter.org/docs/parallelcolt/api/ - Processing
https://www.processing.org/ - The R Project for Statistical Computing
https://www.r-project.org/ - Humane test output for clojure.test
https://github.com/pjstadig/humane-test-output - iota
https://github.com/juxt/iota - 5 Differences between clojure.spec and Schema
https://lispcast.com/clojure.spec-vs-schema/ - Schema: Clojure(Script) library for declarative data description and validation
https://github.com/plumatic/schema - Zip archiv s Clojure 1.9.0
http://repo1.maven.org/maven2/org/clojure/clojure/1.9.0/clojure-1.9.0.zip - Clojure 1.9 is now available
https://clojure.org/news/2017/12/08/clojure19 - Deps and CLI Guide
https://clojure.org/guides/deps_and_cli - Changes to Clojure in Version 1.9
https://github.com/clojure/clojure/blob/master/changes.md - clojure.spec – Rationale and Overview
https://clojure.org/about/spec - Zip archiv s Clojure 1.8.0
http://repo1.maven.org/maven2/org/clojure/clojure/1.8.0/clojure-1.8.0.zip - Clojure 1.8 is now available
http://clojure.org/news/2016/01/19/clojure18 - Socket Server REPL
http://dev.clojure.org/display/design/Socket+Server+REPL - CLJ-1671: Clojure socket server
http://dev.clojure.org/jira/browse/CLJ-1671 - CLJ-1449: Add clojure.string functions for portability to ClojureScript
http://dev.clojure.org/jira/browse/CLJ-1449 - Launching a Socket Server
http://clojure.org/reference/repl_and_main#_launching_a_socket_server - API for clojure.string
http://clojure.github.io/clojure/branch-master/clojure.string-api.html - Clojars:
https://clojars.org/ - Seznam knihoven na Clojars:
https://clojars.org/projects - Clojure Cookbook: Templating HTML with Enlive
https://github.com/clojure-cookbook/clojure-cookbook/blob/master/07_webapps/7–11_enlive.asciidoc - An Introduction to Enlive
https://github.com/swannodette/enlive-tutorial/ - Enlive na GitHubu
https://github.com/cgrand/enlive - Expectations: příklady atd.
http://jayfields.com/expectations/ - Expectations na GitHubu
https://github.com/jaycfields/expectations - Lein-expectations na GitHubu
https://github.com/gar3thjon3s/lein-expectations - Testing Clojure With Expectations
https://semaphoreci.com/blog/2014/09/23/testing-clojure-with-expectations.html - Clojure testing TDD/BDD libraries: clojure.test vs Midje vs Expectations vs Speclj
https://www.reddit.com/r/Clojure/comments/1viilt/clojure_testing_tddbdd_libraries_clojuretest_vs/ - Testing: One assertion per test
http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html - Rewriting Your Test Suite in Clojure in 24 hours
http://blog.circleci.com/rewriting-your-test-suite-in-clojure-in-24-hours/ - Clojure doc: zipper
http://clojuredocs.org/clojure.zip/zipper - Clojure doc: parse
http://clojuredocs.org/clojure.xml/parse - Clojure doc: xml-zip
http://clojuredocs.org/clojure.zip/xml-zip - Clojure doc: xml-seq
http://clojuredocs.org/clojure.core/xml-seq - Parsing XML in Clojure
https://github.com/clojuredocs/guides - Clojure Zipper Over Nested Vector
https://vitalyper.wordpress.com/2010/11/23/clojure-zipper-over-nested-vector/ - Understanding Clojure's PersistentVector implementation
http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation - Understanding Clojure's PersistentHashMap (deftwice…)
http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice.html - Assoc and Clojure's PersistentHashMap: part ii
http://blog.higher-order.net/2010/08/16/assoc-and-clojures-persistenthashmap-part-ii.html - Ideal Hashtrees (paper)
http://lampwww.epfl.ch/papers/idealhashtrees.pdf - Clojure home page
http://clojure.org/ - Clojure (downloads)
http://clojure.org/downloads - Clojure Sequences
http://clojure.org/sequences - Clojure Data Structures
http://clojure.org/data_structures - The Structure and Interpretation of Computer Programs: 2.2.1 Representing Sequences
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-15.html#%_sec2.2.1 - The Structure and Interpretation of Computer Programs: 3.3.1 Mutable List Structure
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-22.html#%_sec3.3.1 - Clojure – Functional Programming for the JVM
http://java.ociweb.com/mark/clojure/article.html - Clojure quick reference
http://faustus.webatu.com/clj-quick-ref.html - 4Clojure
http://www.4clojure.com/ - ClojureDoc (rozcestník s dokumentací jazyka Clojure)
http://clojuredocs.org/ - Clojure (na Wikipedia EN)
http://en.wikipedia.org/wiki/Clojure - Clojure (na Wikipedia CS)
http://cs.wikipedia.org/wiki/Clojure - SICP (The Structure and Interpretation of Computer Programs)
http://mitpress.mit.edu/sicp/ - Pure function
http://en.wikipedia.org/wiki/Pure_function - Funkcionální programování
http://cs.wikipedia.org/wiki/Funkcionální_programování - Čistě funkcionální (datové struktury, jazyky, programování)
http://cs.wikipedia.org/wiki/Čistě_funkcionální - Clojure Macro Tutorial (Part I, Getting the Compiler to Write Your Code For You)
http://www.learningclojure.com/2010/09/clojure-macro-tutorial-part-i-getting.html - Clojure Macro Tutorial (Part II: The Compiler Strikes Back)
http://www.learningclojure.com/2010/09/clojure-macro-tutorial-part-ii-compiler.html - Clojure Macro Tutorial (Part III: Syntax Quote)
http://www.learningclojure.com/2010/09/clojure-macro-tutorial-part-ii-syntax.html - Tech behind Tech: Clojure Macros Simplified
http://techbehindtech.com/2010/09/28/clojure-macros-simplified/ - Fatvat – Exploring functional programming: Clojure Macros
http://www.fatvat.co.uk/2009/02/clojure-macros.html - Eulerovo číslo
http://cs.wikipedia.org/wiki/Eulerovo_číslo - List comprehension
http://en.wikipedia.org/wiki/List_comprehension - List Comprehensions in Clojure
http://asymmetrical-view.com/2008/11/18/list-comprehensions-in-clojure.html - Clojure Programming Concepts: List Comprehension
http://en.wikibooks.org/wiki/Clojure_Programming/Concepts#List_Comprehension - Clojure core API: for macro
http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/for - cirrus machina – The Clojure for macro
http://www.cirrusmachina.com/blog/comment/the-clojure-for-macro/ - Riastradh's Lisp Style Rules
http://mumble.net/~campbell/scheme/style.txt - Dynamic Languages Strike Back
http://steve-yegge.blogspot.cz/2008/05/dynamic-languages-strike-back.html - Scripting: Higher Level Programming for the 21st Century
http://www.tcl.tk/doc/scripting.html - Java Virtual Machine Support for Non-Java Languages
http://docs.oracle.com/javase/7/docs/technotes/guides/vm/multiple-language-support.html - Třída java.lang.String
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html - Třída java.lang.StringBuffer
http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html - Třída java.lang.StringBuilder
http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html - StringBuffer versus String
http://www.javaworld.com/article/2076072/build-ci-sdlc/stringbuffer-versus-string.html - Threading macro (dokumentace k jazyku Clojure)
https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/-> - Understanding the Clojure → macro
http://blog.fogus.me/2009/09/04/understanding-the-clojure-macro/ - clojure.inspector
http://clojure.github.io/clojure/clojure.inspector-api.html - The Clojure Toolbox
http://www.clojure-toolbox.com/ - Unit Testing in Clojure
http://nakkaya.com/2009/11/18/unit-testing-in-clojure/ - Testing in Clojure (Part-1: Unit testing)
http://blog.knoldus.com/2014/03/22/testing-in-clojure-part-1-unit-testing/ - API for clojure.test – Clojure v1.6 (stable)
https://clojure.github.io/clojure/clojure.test-api.html - Leiningen: úvodní stránka
http://leiningen.org/ - Leiningen: Git repository
https://github.com/technomancy/leiningen - leiningen-win-installer
http://leiningen-win-installer.djpowell.net/ - Clojure.org: Vars and the Global Environment
http://clojure.org/Vars - Clojure.org: Refs and Transactions
http://clojure.org/Refs - Clojure.org: Atoms
http://clojure.org/Atoms - Clojure.org: Agents as Asynchronous Actions
http://clojure.org/agents - Transient Data Structureshttp://clojure.org/transients
- Programovací jazyk Clojure a práce s Gitem (2)
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-prace-s-gitem-2/ - Programovací jazyk Clojure – triky při práci s řetězci
http://www.root.cz/clanky/programovaci-jazyk-clojure-triky-pri-praci-s-retezci/ - Programovací jazyk Clojure – triky při práci s kolekcemi
http://www.root.cz/clanky/programovaci-jazyk-clojure-triky-pri-praci-s-kolekcemi/ - Programovací jazyk Clojure – práce s mapami a množinami
http://www.root.cz/clanky/programovaci-jazyk-clojure-prace-s-mapami-a-mnozinami/ - Programovací jazyk Clojure – základy zpracování XML
http://www.root.cz/clanky/programovaci-jazyk-clojure-zaklady-zpracovani-xml/ - Programovací jazyk Clojure – testování s využitím knihovny Expectations
http://www.root.cz/clanky/programovaci-jazyk-clojure-testovani-s-vyuzitim-knihovny-expectations/ - Programovací jazyk Clojure – některé užitečné triky použitelné (nejenom) v testech
http://www.root.cz/clanky/programovaci-jazyk-clojure-nektere-uzitecne-triky-pouzitelne-nejenom-v-testech/ - Enlive – výkonný šablonovací systém pro jazyk Clojure
http://www.root.cz/clanky/enlive-vykonny-sablonovaci-system-pro-jazyk-clojure/ - Nástroj Leiningen a programovací jazyk Clojure: tvorba vlastních knihoven pro veřejný repositář Clojars
http://www.root.cz/clanky/nastroj-leiningen-a-programovaci-jazyk-clojure-tvorba-vlastnich-knihoven-pro-verejny-repositar-clojars/ - Novinky v Clojure verze 1.8.0
http://www.root.cz/clanky/novinky-v-clojure-verze-1–8–0/ - Asynchronní programování v Clojure s využitím knihovny core.async
http://www.root.cz/clanky/asynchronni-programovani-v-clojure-s-vyuzitim-knihovny-core-async/ - Asynchronní programování v Clojure s využitím knihovny core.async (pokračování)
http://www.root.cz/clanky/asynchronni-programovani-v-clojure-s-vyuzitim-knihovny-core-async-pokracovani/ - Asynchronní programování v Clojure s využitím knihovny core.async (dokončení)
http://www.root.cz/clanky/asynchronni-programovani-v-clojure-s-vyuzitim-knihovny-core-async-dokonceni/ - Vytváříme IRC bota v programovacím jazyce Clojure
http://www.root.cz/clanky/vytvarime-irc-bota-v-programovacim-jazyce-clojure/ - Gorilla REPL: interaktivní prostředí pro programovací jazyk Clojure
https://www.root.cz/clanky/gorilla-repl-interaktivni-prostredi-pro-programovaci-jazyk-clojure/ - Multimetody v Clojure aneb polymorfismus bez použití OOP
https://www.root.cz/clanky/multimetody-v-clojure-aneb-polymorfismus-bez-pouziti-oop/ - Práce s externími Java archivy v programovacím jazyku Clojure
https://www.root.cz/clanky/prace-s-externimi-java-archivy-v-programovacim-jazyku-clojure/