Clojure

Z Wikipedie, otevřené encyklopedie
Skočit na: Navigace, Hledání
Clojure
Logo
Paradigma: funkcionální, multiparadigmový
Vznikl v: 2007
Vývojář: Rich Hickey
Poslední verze: 1.3 / 2011-09-23
Ovlivněn jazyky: Lisp, ML, Haskell, Erlang[1]
OS: Multiplatformní
Licence: Eclipse Public License
Web: http://clojure.org

Clojure 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í.[2][3]

Clojure používá pro řízení souběžnosti koncept tzv. identit,[4] 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ý 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. Rich Hickey. Books that influenced Clojure [online]. 30 June 2009, [cit. 2009-09-11]. Dostupné online.  
  2. Rationale [online]. clojure.org, [cit. 2008-10-17]. (Rich Hickey.) Dostupné online.  
  3. Expert to Expert: Rich Hickey and Brian Beckman – Inside Clojure | Going Deep | Channel 9
  4. On State and Identity [online]. clojure.org, [cit. 2010-03-01]. (Rich Hickey.) Dostupné online.  

Literatura[editovat | editovat zdroj]

Externí odkazy[editovat | editovat zdroj]