Clojure (/'klo'uʒə/ ?/i[2]) – nowoczesny dialekt języka programowania Lisp opracowany przez Richa Hickeya. Jest to język ogólnego przeznaczenia, wspierający modyfikację uruchomionego programu oraz zachęcający do programowania funkcyjnego oraz współbieżnego.
Clojure akcentuje niezmienność struktur danych jako kluczową technikę ułatwiającą programowanie współbieżne. Działa na wirtualnej maszynie Javy. Może być uruchamiany przez interpreter albo kompilowany do kodu bajtowego. Można w nim tworzyć aplety, aplikacje, albo Serwlety, co dopuszcza wykonywanie aplikacji internetowych w całości w języku Clojure. Cały język mieści się w jednym pliku jar. Ma rozbudowany system makr znany z Lispu, dzięki czemu da się rozszerzać język o nowe konstrukcje. Posiada jedną przestrzeń nazw dla funkcji oraz zmiennych tak jak Scheme. Posiada pełną integrację z językiem Java, da się uruchamiać kod Clojure z poziomu Javy jak oraz kod Javy z poziomu Clojure.
Etymologia nazwy
Rich Hickey – twórca języka Clojure
Nazwa Clojure pochodzi od słowa Closure (domknięcie), które jest ważnym elementem języka Lisp, z literą s zamienioną na j, wskazująca Javę. Autor chciał utworzyć nazwę, która nawiązywałaby do C#, Lispa oraz Javy[2] oraz to właśnie dlatego wybrał to słowo na nazwę swojego języka programowania.
Pewne cechy języka
- Kompilowany do kodu bajtowego JVM (ang. Java Virtual Machine, wirtualna maszyna Javy);
- Pełna kompatybilność z Javą: Clojure natywnie wywołuje metody Javy oraz na odwrót;
- Możliwość pracy w trybie interaktywnym REPL (ang. read–eval–print loop, pętla wczytaj–wykonaj–wypisz);
- Domknięcia z naciskiem na rekurencję;
- Bogata biblioteka stałych struktur danych;
- Silne wsparcie dla współbieżności w postaci transakcyjnej pamięci (ang. Software Transactional Memory – STM) oraz systemu
agentów.
Przykłady
Uruchomienie REPL
java -cp clojure.jar clojure.main
Wypisywanie tekstu
Definicja zmiennej
(def zmienna (+ 2 (* 4 5)))
Definicja funkcji
Funkcja obliczająca silnie (nazwy zmiennych tj. symboli, tak jak w innych dialektach języka lisp potrafią się składać z dowolnych znaków).
(defn ! x
(if (= x 0)
1
(* x (! (- x 1)))))
Funkcje anonimowe
Funkcje wyższego rzędu
(defn f x
(* 2 (/ 3 4)))
(map f '(3 4 5 6 7 8))
;; Lub to samo używając funkcji anonimowej:
(map (fn x (* 2 (/ 3 4))) '(3 4 5 6 7 8))
Makra
Makro define służące do definiowania funkcji jak w Scheme. W przeciwieństwie od innych dialektów, do obliczenia wyrażenia wewnątrz cytowania Quasi-quotation, zamiast przecinka używa się znaku tyldy.
(defmacro define params & body
`(defn ~(first params) ~@(rest params) ~@body))
(define (f x) (* x x))
(f 10)
Wykonywanie nowego obiektu Javy
(new java.lang.String "Hello world!")
Wywoływanie metody obiektu
(defn upper s (.toUpperCase s))
(upper (new java.lang.String "foo bar"))
Wywyoływanie metody statycznej
Funkcja string → integer występująca w języku Scheme.
(defn string→integer
(str
(Integer/parseInt str 10))
(str base
(Integer/parseInt str base)))
GUI
Użycie biblioteki Swing.
(javax.swing.JOptionPane/showMessageDialog nil "Hello world!")
Sprawdź też
Linki zewnętrzne
Bibliografia
- Rationale. W: Rich Hickey [on-line]. clojure.org. [dostęp 2011-07-18].
Przypisy