Daha önce de bahsettiğimiz gibi clojure fonksiyonel bir programlama dilidir. Clojure ile iki şekilde fonksiyon tanımlanabilir.
(def toplam (fn [x y] (+ x y)))
diğer tanımlama ise defn makrosu ile olur.
(defn toplam [x y] (+ x y))
Fonksiyonlar defn ile tanımlanırken içerik açıklaması eklenebilir.
(defn toplam "toplama yapan bizim programımız" [x y] (+ x y))
bu açıklama satırını okumak için doc metodunu kullanırız
(doc toplam)
dilersek yukarıdaki toplam fonksiyonunun parametrelerine de sınırlama getirebiliriz.
(defn toplam "bizim yazdığımız 2 den büyük sayıların toplamını alan ve sonuç 10 dan küçükse hata veren fonksiyon" [x y] {:pre [(> x 2) (> y 2)] :post [(> % 10)]} (+ x y))
bu program (toplam 3 4) gibi bir çıktıya hata verir. kontrol yapısı bir map olmalıdır ve iki anahtar kelimesi vardır. :pre anahtar kelimesi girdileri :post anahtar kelimesi ise çıktıları kontrol eder.
Clojure ortamında bir fonksiyona birden çok parametre mimarisi verilerek fonksiyonlar aşırı yüklenebilir.
(defn ozeltoplam ([x y z] (+ x y z)) ([x y] (ozeltoplam x y 1)))
Clojure fonksiyonlarına birden çok oge alan parametreler geçilebilir.
(defn varprog [& lines] (apply + lines))
Buradaki & işareti birden çok parametreyi ifade eder lines bu durumda bir vektör olur.
Clojure ortamında pek çok fonksiyon yapısı gereği özyinelemelidir.
(defn gerisay [n] (if (zero? n) n (do (println n) (gerisay (dec n)))))
fakat clojure yukarıdaki gibi bir özyinelemede stack kullanır. Stack kullanmadan tail recurisive yaratmak için recur yapısı kullanılmalıdır.
(defn gerisay [n] (if (zero? n) n (do (println n) (recur (dec n)))))
eğer birbirini sıra ile şağıran yinelemeler varsa
(declare ucazalt) (defn birarttir [n] (if-not (zero? n) (do (println n) #(ucazalt (inc n))))) (defn ucazalt [n] (if-not (zero? n) (do (println n) #(birarttir (- n 3))))) (trampoline birarttir 5)
yapısı kullanılabilir. trampoline özyinelemelerin bellek çıkmazını çözer.
Clojure ortamında bir fonksiyon iki şekilde cağrılabilir. Bunlar
(+ 1 2 3)
veya
(apply + [1 2 3])
ÅŸeklinde olur.