Clojure

Z Wikipedie, otevřené encyklopedie
Clojure
Paradigmafunkcionální, multiparadigmový
Vznik2007
VývojářRich Hickey
První vydání2007
Poslední verze1.9.0 (8. prosince 2017[1])
Typová kontroladynamické, silné
Ovlivněn jazykyLisp, ML, Haskell, Erlang[2]
Ovlivnil jazykyElixir, Hy, Pixie, Rhine
OSMultiplatformní
LicenceEclipse Public License
Webclojure.org

Clojure (výslovnost [ˈkloužəːr]) je v informatice moderní dialekt programovacího jazyka Lisp. Jedná se o univerzální jazyk podporující funkcionální programování, který se zaměřuje na zjednodušení vývoje vícevláknových aplikací. Clojure používá běhové prostředí JVM nebo CLR, přičemž zastává filozofii kódu, který se chová jako data a implementuje sofistikovaný Lispový makrosystém.

Filozofie[editovat | editovat zdroj]

Rich Hickey vyvinul Clojure, protože si přál moderní Lisp spolupracující s rozšířenou platformou Java, který by byl navržen pro vývoj vícevláknových aplikací.[3][4]

Clojure používá pro řízení souběžnosti koncept tzv. identit,[5] který si lze představit jako sérii v čase neměnitelných stavů. Jelikož tyto stavy mají neměnitelné hodnoty, může nad nimi paralelně operovat jakýkoliv počet vláken a řízení souběžnosti se stává otázkou spravování přechodů z jednoho stavu do dalšího. Pro tento účel Clojure poskytuje 4 měnitelné referenční typy, kde každý má jasně definovanou sémantiku pro přechod mezi stavy.

Syntaxe[editovat | editovat zdroj]

Jako každý Lisp, syntaxe jazyka Clojure je postavena na s-výrazech, které jsou nejprve rozebrány do datových struktur před tím než jsou zkompilovány. Clojure podporuje literály pro struktury jako seznamy, mapy, množiny a pole, které jsou kompilátoru předány tak jak jsou. Clojure je Lisp-1 a není zamýšleno, aby byl kompatibilní s ostatními dialekty Lispu.

Makra[editovat | editovat zdroj]

Makro je konstrukce, které v argumentech předáme S-výrazy, ze kterých je následně sestaven libovolný kód. Poté se tento kód vykoná. Systém maker v Clojuru je velice podobný kódu Common Lispu.

Vlastnosti jazyka[editovat | editovat zdroj]

  • dynamický vývoj pomocí REPL
  • funkce jsou first-class objekty s důrazem na rekurzi namísto smyček vytvářejících postranní efekty
  • líně vyhodnocované sekvence
  • poskytuje bohatou sadu neměnitelných datových struktur
  • souběžné programování pomocí softwarové transakční paměti, agentový systém a dynamický typový systém
  • multimetody poskytují dynamické spuštění metod, jejichž konkrétní implementace je vybrána na základě typu předaných parametrů
  • jazyk je kompilovaný do JVM bajtkódu
  • silná integrace s Javou: kód jazyka Clojure kompilovaný do JVM bajtkódu může být snadno nasazený do běžného prostředí JVM a aplikačních serverů bez dalších potíží; jazyk dále poskytuje makra, která usnadňují použití existujících Java API; jeho struktury implementují standardní rozhraní Javy, což umožňuje spouštět kód napsaný v Clojure z Javy

Příklady[editovat | editovat zdroj]

Ahoj světe[editovat | editovat zdroj]

(println "Ahoj světe!")

GUI verze[editovat | editovat zdroj]

(javax.swing.JOptionPane/showMessageDialog nil "Ahoj světe")

Vláknově bezpečný generátor unikátních sériových čísel[editovat | editovat zdroj]

(let [i (atom 0)]
  (defn generate-unique-id
    "Vrací různá číselná ID pro každé volání."
    []
    (swap! i inc)))

Anonymní podtřída java.io.Writer[editovat | editovat zdroj]

Tato třída nikam nezapisuje a obsahuje makro, které umlčí všechno vypisování.

(def bit-bucket-writer
  (proxy [java.io.Writer] []
    (write [buf] nil)
    (close []    nil)
    (flush []    nil)))

(defmacro noprint
  "Vykoná předané výrazy a umlčí všechna vypisování na *out* (standardní výstup)."
  [& forms]
  `(binding [*out* bit-bucket-writer]
     ~@forms))

(noprint
 (println "Zdravím nikoho!"))

Vlákna[editovat | editovat zdroj]

Následující příklad ukazuje 10 vláken operujících nad společnou datovou strukturou, která se skládá ze 100 vektorů, každý obsahující 10 (zpočátku po sobě jdoucích) unikátních čísel. Každé vlákno vybírá 2 náhodné pozice ve 2 náhodných vektorech a prohazuje je. Všechny změny ve vektorech probíhají v transakcích s použitím softwarové transakční paměti, a proto ani po 100 000 iteracích každého vlákna se neztratí žádné číslo.

(defn run [nvecs nitems nthreads niters]
  (let [vec-refs (vec (map (comp ref vec)
                           (partition nitems (range (* nvecs nitems)))))
        swap #(let [v1 (rand-int nvecs)
                    v2 (rand-int nvecs)
                    i1 (rand-int nitems)
                    i2 (rand-int nitems)]
                (dosync
                 (let [temp (nth @(vec-refs v1) i1)]
                   (alter (vec-refs v1) assoc i1 (nth @(vec-refs v2) i2))
                   (alter (vec-refs v2) assoc i2 temp))))
        report #(do
                 (prn (map deref vec-refs))
                 (println "Distinct:"
                          (count (distinct (apply concat (map deref vec-refs))))))]
    (report)
    (dorun (apply pcalls (repeat nthreads #(dotimes [_ niters] (swap)))))
    (report)))

(run 100 10 10 100000)

Výstup[editovat | editovat zdroj]

([0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17 18 19] 
 [990 991 992 993 994 995 996 997 998 999])
Distinct: 1000
 
([382 318 466 963 619 22 21 273 45 596] [808 639 804 471 394 904 952 75 289 778] 
 [484 216 622 139 651 592 379 228 242 355])
Distinct: 1000

Reference[editovat | editovat zdroj]

  1. Central Repository: org/clojure/clojure/1.9.0 [online]. Rev. 2017-12-08 [cit. 2018-02-23]. Dostupné online. (anglicky) [nedostupný zdroj]
  2. HICKEY, Rich. Books that influenced Clojure [online]. 2009-06-30 [cit. 2018-02-23]. Dostupné online. (anglicky) 
  3. Clojure - Rationale [online]. Rich Hickey, 2018-02-21 [cit. 2018-02-23]. Dostupné online. (anglicky) 
  4. Charles. Expert to Expert: Rich Hickey and Brian Beckman - Inside Clojure [online]. Microsoft, 2009-10-06 [cit. 2018-02-23]. (Channel 9. Going Deep). Dostupné online. (anglicky) 
  5. Clojure - Values and Change: Clojure‘s approach to Identity and State [online]. Rich Hickey, 2018-02-21 [cit. 2018-02-23]. Dostupné online. (anglicky) 

Literatura[editovat | editovat zdroj]

Externí odkazy[editovat | editovat zdroj]