Hlavní navigace

Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (dokončení)

Pavel Tišnovský 26. 5. 2015

V poslední části článku o programovacím jazyku Clojure a o knihovně Clisk si ukážeme vestavěné (předdefinované) textury, které jsou součástí zdrojových kódů knihovny Clisk. Druhá část článku bude věnována problematice Voroného diagramů a jejich použití při tvorbě vlastních textur. Nebude chybět ani téměř 30 ukázkových textur.

Obsah

1. Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (dokončení)

2. Vestavěné deklarace textur (předdefinované textury)

3. Úplný zdrojový kód demonstračního příkladu clisktest6

4. Voroného diagramy a jejich využití při tvorbě textur

5. Použití Voroného diagramů v praxi

6. Úplný zdrojový kód demonstračního příkladu clisktest7

7. Repositář s demonstračními příklady

8. Odkazy na předchozí části seriálu

9. Odkazy na Internetu

1. Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (dokončení)

V předchozích dvou částech seriálu o programovacím jazyku Clojure a o knihovně Clisk jsme si vysvětlili, jakým způsobem se v této knihovně tvoří procedurální textury. Ukázali jsme si použití několika algoritmů používaných pro tvorbu textur, které mají připomínat přírodní (nepravidelné) povrchy, například písek, mramor či dřevo. Taktéž jsme se zmínili o možnosti vykreslování fraktálů, i když použití fraktálů pro tvorbu textur nemusí být ve všech případech praktické. V dnešním článku popis knihovny Clisk dokončíme. Nejdříve se zmíníme o předdefinovaných texturách, které je možné použít prakticky ihned a následně si ukážeme aplikaci Voroného diagramů (Voronoi diagram) pro tvorbu textur, protože se jedná o velmi užitečnou část knihovny Clisk, společně s podporou Perlinova šumu (Perlin Noise) popsaného minule.

Obrázek 1: Textura deklarovaná následovně:
(offset (v* 0.1 (scale 0.03 vsnoise)) (rgb-from-hsl (v+ [0 0 0.5] (scale 0.3 vsnoise))))
Autor: Mike Anderson

2. Vestavěné deklarace textur (předdefinované textury)

Jak jsme se dozvěděli v předchozích textech, nabízí knihovna Clisk svým uživatelům možnost vytvoření prakticky jakkoli komplexní procedurální textury. Pro tvorbu textury lze používat jak vestavěné funkce (pracující s až čtyřsložkovými vektory), tak i již zmíněnou funkci pro tvorbu Perlinova šumu, několik funkcí pro vytváření pravidelných vzorků (mřížka, šachovnice, soustředné kružnice) atd. Kromě můžeme v této knihovně nalézt i několik předdefinovaných textur, jejichž význam je dvojí – lze je (samozřejmě) přímo použít například ve hrách, ovšem důležitější je fakt, že se uživatelé mohou naučit, jakým způsobem lze efektivně používat všechny funkce touto knihovnou nabízené. Mezi předdefinované textury patří:

# Textura Interně se používá
1 agate plasma
2 clouds plasma
3 velvet Perlinův šum
4 flecks Perlinův šum
5 wood výpočet vzdálenosti od středu

Všech pět výše zmíněných textur si můžeme v základní podobě (bez použití barvové palety atd.) jednoduše otestovat:

(defn predefined-textures-test
    []
    (let [textures [agate
                    clouds
                    velvet
                    flecks
                    wood]]
        ; postupně projít všemi prvky vektoru "textures", vytvořit
        ; dvouprvkový vektor [index+patter], vytvořit jméno výstupního
        ; souboru a následně zavolat funkci write-texture
        (doseq [ [i texture] (map-indexed vector textures)]
            (write-pattern texture (str "texture_" i ".png")))))

Výsledky můžete vidět na obrázcích číslo 2 až 5:

Obrázek 2: Předdefinovaná textura agate.

Obrázek 3: Předdefinovaná textura clouds.

Obrázek 4: Předdefinovaná textura velvet.

Obrázek 5: Předdefinovaná textura flecks.

Obrázek 6: Předdefinovaná textura wood.

3. Úplný zdrojový kód demonstračního příkladu clisktest6

V této kapitole bude uveden výpis úplného zdrojového kódu dnešního prvního demonstračního příkladu nazvaného clisktest6, z něhož jsme použili úryvek a ukázky v předešlé kapitole. Tento příklad po svém spuštění vykreslí vybrané předdefinované textury a uloží je do pětice souborů typu PNG. Většinu funkcí, které jsou v tomto příkladu využity, již známe z předchozích demonstračních příkladů:

Obsah souboru project.clj:

(defproject clisktest6 "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [net.mikera/clisk "0.10.0"]]
  :main ^:skip-aot clisktest6.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})

Obrázek 7: Textura deklarovaná následovně:
(seamless 0.5 (v* [1 0.8 0 0] (compose vnoise [spots y z t])))
Autor: Mike Anderson

Obsah souboru core.clj:

(ns clisktest6.core
    (:gen-class)
    (:use clisk.live))
 
(import java.io.File)
(import javax.imageio.ImageIO)
 
(defn write-image
    "Uložení rastrového obrázku typu BufferedImage do souboru."
    [image file-name]
    (ImageIO/write image "png" (File. file-name)))
 
(defn write-pattern
    "Vytvoření rastrového obrázku na základě předaného patternu."
    [pattern file-name]
    (write-image (image pattern) file-name))
 
(defn predefined-textures-test
    []
    (let [textures [agate
                    clouds
                    velvet
                    flecks
                    wood]]
        ; postupně projít všemi prvky vektoru "textures", vytvořit
        ; dvouprvkový vektor [index+patter], vytvořit jméno výstupního
        ; souboru a následně zavolat funkci write-texture
        (doseq [ [i texture] (map-indexed vector textures)]
            (write-pattern texture (str "texture_" i ".png")))))
 
(defn -main
    [& args]
    (try
        (println "Predefined textures test...")
        (predefined-textures-test)
        (println "Done")
        (catch Throwable e
            (println (.toString e)))
        (finally ; jistota, že program vždy korektně skončí
            (System/exit 0))))

Obrázek 8: Textura deklarovaná následovně:
(v- 1.0 (seamless 0.2 (v* 6 (scale 3 vnoise) (v- 0.1 (vmax 0 (vabs (v- plasma 0.5)))))))
Autor: Mike Anderson

4. Voroného diagramy a jejich využití při tvorbě textur

Poměrně zajímavou a poněkud méně známou pomůckou pro tvorbu procedurálních textur jsou takzvané Voroného diagramy (Voronoi Diagrams). Vytvoření Voroného diagramu v ploše pro účely generování procedurální textury je celkem jednoduché – do plochy se náhodně umístí zvolený počet n bodů b0..bn a následně se celá plocha rozdělí na oblasti, přičemž pro všechny body patřící do jedné oblasti platí, že jejich vzdálenost ke konkrétnímu bodu bi je menší než vzdálenost k jakémukoli jinému bodu bj. Příklad takto zkonstruovaného diagramu lze nalézt například na stránce http://upload.wikimedia.or­g/wikipedia/commons/8/80/E­uclidean_Voronoi_Diagram.png. Tento postup lze rozšířit i do 3D a 4D prostoru a navíc je pro účely vytváření textur vhodnější neobarvovat každou plochu konstantní barvou, ale zvolit gradientní přechod na základě skutečné vzdálenosti každého bodu od hranice oblasti.

Pro vytvoření procedurální textury se používá funkce voronoi-map společně s funkcí voronoi-blocks (právě zde se počítá gradientní přechod). Základním parametrem pro tvorbu takové textury je počet počátečních bodů, který určuje počet oblastí a tím pádem i „měřítko“ textury. Minimální počet bodů je 3, maximální počet bodů je 1000:

(defn voronoi-map-test
    []
    (doseq [i (range 2 10)]
         (let [voronoi-map (voronoi :points (bit-shift-left 1 i))
               pattern     (voronoi-blocks :voronoi voronoi-map)
               file-name   (format "%02d.png" i)]
               (write-pattern pattern file-name))))

Obrázek 9: (voronoi :points 4).

Obrázek 10: (voronoi :points 8)

Obrázek 11: (voronoi :points 16)

Obrázek 12: (voronoi :points 32)

Obrázek 13: (voronoi :points 64)

Obrázek 14: (voronoi :points 128)

Obrázek 15: (voronoi :points 256)

Obrázek 16: (voronoi :points 512)

5. Použití Voroného diagramů v praxi

Již z neupravovaných a nemodifikovaných ukázek uvedených ve čtvrté kapitole je patrné, že se Voroného diagramy mohou využít pro tvorbu textur, které mohou připomínat například rozpraskané sklo, hlínu či povrchy některých hornin. Po vizuální stránce je velmi zajímavá kombinace dvou Voroného diagramů – jeden může sloužit pro určení světlosti pixelů, druhý pak pro výběr barvy. K tomuto účelu lze využít funkci wrap popř. funkci nazvanou rgb-from-hsl, která dokáže provést transformaci libovolné barvy (minimálně trojsložkového vektoru) z barvového prostoru HSL do barvového prostoru RGB. Zajímavé je i použití výsledku výpočtu barvy bodu ve Voroného diagramu pro offset (viz též předposlední část tohoto článku). Podívejme se nyní na několik ukázek vytvořených demonstračním příkladem clisktest7, jehož zdrojový kód je vypsán v šesté kapitole:

Obrázek 17: Textura vytvořená pomocí výrazu (voronoi-blocks :voronoi voronoi1).

Obrázek 18: Textura vytvořená pomocí výrazu (voronoi-blocks :voronoi voronoi2).

Obrázek 19: Textura vytvořená pomocí výrazu (voronoi-blocks :voronoi voronoi3).

Obrázek 20: Textura vytvořená pomocí výrazu (v* 2.0 (voronoi-blocks :voronoi voronoi1)).

Obrázek 21: Textura vytvořená pomocí výrazu (v* 2.0 (voronoi-blocks :voronoi voronoi2)).

Obrázek 22: Textura vytvořená pomocí výrazu (v* 2.0 (voronoi-blocks :voronoi voronoi3)).

Obrázek 23: Textura vytvořená pomocí výrazu (v* (v* 20.0 (voronoi-blocks :voronoi voronoi2)) (warp (voronoi-points :voronoi voronoi1) grain)).

Obrázek 24: Textura vytvořená pomocí výrazu (v* (v* 20.0 (voronoi-blocks :voronoi voronoi2)) (warp (voronoi-points :voronoi voronoi2) grain)).

Obrázek 25: Textura vytvořená pomocí výrazu (v* (v* 20.0 (voronoi-blocks :voronoi voronoi3)) (warp (voronoi-points :voronoi voronoi3) grain)).

6. Úplný zdrojový kód demonstračního příkladu clisktest7

Následuje výpis zdrojového kódu dnešního druhého a současně i posledního demonstračního příkladu nazvaného clisktest7:

Obsah souboru project.clj:

(defproject clisktest7 "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [net.mikera/clisk "0.10.0"]]
  :main ^:skip-aot clisktest7.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})

Obrázek 26: Textura deklarovaná následovně:
(seamless 1.0 (offset (v* 4 vplasma) (v+ (offset 10 vnoise) 0.3)))
Autor: Mike Anderson

Obsah souboru core.clj:

(ns clisktest7.core
    (:gen-class)
    (:use clisk.live))
 
(import java.io.File)
(import javax.imageio.ImageIO)
 
(defn write-image
    "Uložení rastrového obrázku typu BufferedImage do souboru."
    [image file-name]
    (ImageIO/write image "png" (File. file-name)))
 
(defn write-pattern
    "Vytvoření rastrového obrázku na základě předaného patternu."
    [pattern file-name]
    (write-image (image pattern) file-name))
 
(defn voronoi-map-test
    []
    (let [voronoi1 (voronoi :points 10)
          voronoi2 (voronoi :points 100)
          voronoi3 (voronoi :points 1000)]
         (write-pattern (voronoi-blocks :voronoi voronoi1) "voronoi1.png")
         (write-pattern (voronoi-blocks :voronoi voronoi2) "voronoi2.png")
         (write-pattern (voronoi-blocks :voronoi voronoi3) "voronoi3.png")
         (write-pattern (v* 2.0 (voronoi-blocks :voronoi voronoi1)) "voronoi4.png")
         (write-pattern (v* 2.0 (voronoi-blocks :voronoi voronoi2)) "voronoi5.png")
         (write-pattern (v* 2.0 (voronoi-blocks :voronoi voronoi3)) "voronoi6.png")
         (write-pattern (v* (v* 20.0 (voronoi-blocks :voronoi voronoi2))
                        (warp (voronoi-points :voronoi voronoi1) grain)) "voronoi7.png")
         (write-pattern (v* (v* 20.0 (voronoi-blocks :voronoi voronoi2))
                        (warp (voronoi-points :voronoi voronoi2) grain)) "voronoi8.png")
         (write-pattern (v* (v* 20.0 (voronoi-blocks :voronoi voronoi3))
                        (warp (voronoi-points :voronoi voronoi3) grain)) "voronoi9.png")))
 
(defn -main
    [& args]
    (try
        (println "Voronoi map test...")
        (voronoi-map-test)
        (println "Done")
        (catch Throwable e
            (println (.toString e)))
        (finally ; jistota, že program vždy korektně skončí
            (System/exit 0))))

Obrázek 27: Textura deklarovaná následovně:
(seamless 0.25 (compose plasma vsnoise))
Autor: Mike Anderson

7. Repositář s demonstračními příklady

Oba dva dnes popsané demonstrační příklady byly, podobně jako v předchozích částech tohoto seriálu, uloženy do GIT repositáře dostupného na adrese https://github.com/tisnik/clojure-examples. V tabulce zobrazené pod tímto odstavcem naleznete na jednotlivé příklady přímé odkazy:

Obrázek 28: Textura deklarovaná následovně:
(seamless 0.4 (v- vnoise (v* 6 (v- 0.1 (vmax 0 (vabs (v- plasma 0.5)))))))
Autor: Mike Anderson

8. Odkazy na předchozí části seriálu

  1. Leiningen: nástroj pro správu projektů napsaných v Clojure
    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 (2)
    http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-2/
  3. 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/
  4. 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/
  5. 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/
  6. 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/
  7. Programovací jazyk Clojure a databáze (1.část)
    http://www.root.cz/clanky/programovaci-jazyk-clojure-a-databaze-1-cast/
  8. Pluginy pro Leiningen
    http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-pluginy-pro-leiningen/
  9. 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/
  10. 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-2/
  11. 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/
  12. 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/

Obrázek 29: Textura deklarovaná následovně:
(seamless 1.0 (compose (scale 0.01 (checker 0 1)) plasma))
Autor: Mike Anderson

9. Odkazy na Internetu

  1. Clisk
    https://github.com/mikera/clisk
  2. clojars: net.mikera/clisk
    https://clojars.org/net.mikera/clisk
  3. clojure.inspector
    http://clojure.github.io/clo­jure/clojure.inspector-api.html
  4. Clisk: wiki
    https://github.com/mikera/clisk/wiki
  5. Dokumentace vygenerovaná pro knihovnu core.matrix
    https://cloojure.github.i­o/doc/core.matrix/index.html
  6. Size and Dimensionality
    https://groups.google.com/fo­rum/#!topic/numerical-clojure/zebBCa68eTw/discussion
  7. Towards core.matrix for Clojure?
    https://clojurefun.wordpres­s.com/2013/01/05/towards-core-matrix-for-clojure/
  8. The Clojure Toolbox
    http://www.clojure-toolbox.com/
  9. Neanderthal
    http://neanderthal.uncomplicate.org/
  10. Hello world project
    https://github.com/uncompli­cate/neanderthal/blob/mas­ter/examples/hello-world/project.clj
  11. vectorz-clj
    https://github.com/mikera/vectorz-clj
  12. vectorz – Examples
    https://github.com/mikera/vectorz-clj/wiki/Examples
  13. gloss
    https://github.com/ztellman/gloss
  14. HTTP client/server for Clojure
    http://www.http-kit.org/
  15. Array Programming
    https://en.wikipedia.org/wi­ki/Array_programming
  16. Discovering Array Languages
    http://archive.vector.org­.uk/art10008110
  17. no stinking loops – Kalothi
    http://www.nsl.com/
  18. Vector (obsahuje odkazy na články, knihy a blogy o programovacích jazycích APL, J a K)
    http://www.vector.org.uk/
  19. APL Interpreters
    http://www.vector.org.uk/?a­rea=interpreters
  20. APL_(programming_language
    http://en.wikipedia.org/wi­ki/APL_(programming_langu­age
  21. APL FAQ
    http://www.faqs.org/faqs/apl-faq/
  22. APL FAQ (nejnovější verze)
    http://home.earthlink.net/~swsir­lin/apl.faq.html
  23. A+
    http://www.aplusdev.org/
  24. APLX
    http://www.microapl.co.uk/
  25. FreeAPL
    http://www.pyr.fi/apl/index.htm
  26. J: a modern, high-level, general-purpose, high-performance programming language
    http://www.jsoftware.com/
  27. K, Kdb: an APL derivative for Solaris, Linux, Windows
    http://www.kx.com
  28. openAPL (GPL)
    http://sourceforge.net/pro­jects/openapl
  29. Parrot APL (GPL)
    http://www.parrotcode.org/
  30. Learning J (Roger Stokes)
    http://www.jsoftware.com/hel­p/learning/contents.htm
  31. Rosetta Code
    http://rosettacode.org/wiki/Main_Page
  32. Why APL
    http://www.acm.org/sigapl/whyapl.htm
  33. java.jdbc API Reference
    https://clojure.github.io/java.jdbc/
  34. Hiccup
    https://github.com/weavejester/hiccup
  35. Clojure Ring na GitHubu
    https://github.com/ring-clojure/ring
  36. A brief overview of the Clojure web stack
    https://brehaut.net/blog/2011/rin­g_introduction
  37. Getting Started with Ring
    http://www.learningclojure­.com/2013/01/getting-started-with-ring.html
  38. Getting Started with Ring and Compojure – Clojure Web Programming
    http://www.myclojureadven­ture.com/2011/03/getting-started-with-ring-and-compojure.html
  39. Unit Testing in Clojure
    http://nakkaya.com/2009/11/18/unit-testing-in-clojure/
  40. Testing in Clojure (Part-1: Unit testing)
    http://blog.knoldus.com/2014/03/22/tes­ting-in-clojure-part-1-unit-testing/
  41. API for clojure.test – Clojure v1.6 (stable)
    https://clojure.github.io/clo­jure/clojure.test-api.html
  42. Leiningen: úvodní stránka
    http://leiningen.org/
  43. Leiningen: Git repository
    https://github.com/techno­mancy/leiningen
  44. leiningen-win-installer
    http://leiningen-win-installer.djpowell.net/
  45. Clojure 1: Úvod
    http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm/
  46. Clojure 2: Symboly, kolekce atd.
    http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-2-cast/
  47. 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/
  48. 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/
  49. 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/
  50. Clojure 6: Podpora pro paralelní programování
    http://www.root.cz/clanky/programovaci-jazyk-clojure-6-futures-nejsou-jen-financni-derivaty/
  51. Clojure 7: Další funkce pro paralelní programování
    http://www.root.cz/clanky/programovaci-jazyk-clojure-7-dalsi-podpurne-prostredky-pro-paralelni-programovani/
  52. 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/
  53. 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/
  54. Clojure 10: Kooperace mezi Clojure a Javou
    http://www.root.cz/clanky/programovaci-jazyk-clojure-10-kooperace-mezi-clojure-a-javou-pokracovani/
  55. Clojure 11: Generátorová notace seznamu/list comprehension
    http://www.root.cz/clanky/programovaci-jazyk-clojure-11-generatorova-notace-seznamu-list-comprehension/
  56. 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/
  57. Clojure 13: Překlad programů z Clojure do bajtkódu JVM II
    2) http://www.root.cz/clanky/programovaci-jazyk-clojure-13-preklad-programu-z-clojure-do-bajtkodu-jvm-pokracovani/
  58. Clojure 14: Základy práce se systémem maker
    http://www.root.cz/clanky/programovaci-jazyk-clojure-14-zaklady-prace-se-systemem-maker/
  59. Clojure 15: Tvorba uživatelských maker
    http://www.root.cz/clanky/programovaci-jazyk-clojure-15-tvorba-uzivatelskych-maker/
  60. Clojure 16: Složitější uživatelská makra
    http://www.root.cz/clanky/programovaci-jazyk-clojure-16-slozitejsi-uzivatelska-makra/
  61. Clojure 17: Využití standardních maker v praxi
    http://www.root.cz/clanky/programovaci-jazyk-clojure-17-vyuziti-standardnich-maker-v-praxi/
  62. Clojure 18: Základní techniky optimalizace aplikací
    http://www.root.cz/clanky/programovaci-jazyk-clojure-18-zakladni-techniky-optimalizace-aplikaci/
  63. Clojure 19: Vývojová prostředí pro Clojure
    http://www.root.cz/clanky/programovaci-jazyk-clojure-19-vyvojova-prostredi-pro-clojure/
  64. 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/
  65. Clojure 21: ClojureScript aneb překlad Clojure do JS
    http://www.root.cz/clanky/programovaci-jazyk-clojure-21-clojurescript-aneb-preklad-clojure-do-javascriptu/
Našli jste v článku chybu?
Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?

Podnikatel.cz: EET: Totálně nezvládli metodologii projektu

EET: Totálně nezvládli metodologii projektu

DigiZone.cz: ČRo rozšiřuje DAB do Berouna

ČRo rozšiřuje DAB do Berouna

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Vitalia.cz: To není kašel! Správná diagnóza zachrání život

To není kašel! Správná diagnóza zachrání život

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí

Vitalia.cz: „Připluly“ z Německa a možná obsahují jed

„Připluly“ z Německa a možná obsahují jed

Měšec.cz: Finančním poradcům hrozí vracení provizí

Finančním poradcům hrozí vracení provizí

DigiZone.cz: Sony KD-55XD8005 s Android 6.0

Sony KD-55XD8005 s Android 6.0

DigiZone.cz: ČT má dalšího zástupce v EBU

ČT má dalšího zástupce v EBU

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

Lupa.cz: UX přestává pro firmy být magie

UX přestává pro firmy být magie

Podnikatel.cz: 1. den EET? Problémy s pokladnami

1. den EET? Problémy s pokladnami

Root.cz: Vypadl Google a rozbilo se toho hodně

Vypadl Google a rozbilo se toho hodně

Měšec.cz: Jak vymáhat výživné zadarmo?

Jak vymáhat výživné zadarmo?

Vitalia.cz: 9 největších mýtů o mase

9 největších mýtů o mase

Podnikatel.cz: Na poslední chvíli šokuje vyjímkami v EET

Na poslední chvíli šokuje vyjímkami v EET