CLOJURE VE FONKSİYONLAR (20)

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.

CLOJURE SEKANSLAR (19)

Pek çok lisp lehçesinde dilin yapısını listeler oluşturmaktadır. Clojure bu kavramı geliştirmiş listeler, hash tabloları, vektorler ve kümeler için sekans demiştir. Sekanslarda üç fonksiyon kullanılır.

(first '(a b c d))

ilk öge first ile alınır. Geri kalan ögeler rest ile çekilebilir.

(rest '(a b c d))

iki seknas tek sekansa cons ile birleşir.

(cons 'a '(b c d))

cons işlemini tersten conj ile de yapabiliriz.

(conj '(1 2 3) '4)

LİSTELER

Listeler kısaca şöyle tanımlanır

(list 1 2 3 4)

Listelerin özel bir yeri vardır temel veri tipi listedir.

VEKTÖRLER

(vector 1 2 3 4)

şeklinde veya

'[1 2 3 4]

şeklinde tanımlanır. vektorden veri çekmek hayli kolaydır.

(def myvec '[a b c d e f g])
(myvec 2)

MAP

Hashmap vektörün gelişmişidir ikili veri tutar

(def mymaptest {a: 1 b: 2 c:3})
(mymaptest a:)

map için diğer metot hash-map ile tanımlanabilir.

(def mymap (hash-map :a 1 :b 2 :c 3))

map’a öge eklemek istersek

(assoc {:a 1 :b 2} :c 4)

öge çokartmak için

(dissoc {:a 1 :b 2 :c 3} :c)

CLOJURE VERİ TİPLERİ (18)

Clojure dört grupta incelenebilecek şekilde veri yapıları ortaya koyar bu kısımda 3 çeşidini görecepiz.

Nil Null ve T

Clojure hava gibi true ve false terimlerini destekler fakat nil adında lispten gelen bir veri de vardır. Clojure ortamında nil boş sekans anlamına gelmez.

Clojure ortamında t true ifadesini karşılar. Boş sekanlar ise null olarak geçer.

Char String ve Number

Karakterler tek harf barındırır. \a bir karakterdir. Karakterler bir araya gelerek stringleri meydana getirir. “elma ye” bir stringtir.

Clojure ortamında string fonksiyonlara . ifadesi ile ulaşılabilinir.

(.split "hello world test" " ")

Clojure ortamı diger lisplerde de olduğu gibi sayı türlerini tutabilir. 3/5 gibi kesirli 3,14 gibi kayar noktalı sayılar olabilir.

Sembol ve Keyword

Clojure ortamı da temel veri tip olarak sekanlarda semboleri kullanır A veya isim birer semboldür. Keywordler ise :isim şeklinde yazılır. Clojure ortamında bir keyword aynı zamanda özel bir get – set fonksiyonudur.

CLOJURE FOR (17)

For yapısı ilk sekanstaki her eleman ile ikinci sekanstaki her aleman arasında ilişki kurup bir fonksiyonu çalıstıran özel bir makrodur.

(for [x '(1 2 3)
      y '(3 4 5)]
  (+ x y))

CLOJURE REDUCE (16)

CLOJURE REDUCE

Bir fonksiyonun sekansın tüm ögelerine uygulanması istendiğinde devreye reduce girer. şöyle kullanılabilir.

(defn rfact [x]
  (let [num (range 1 (inc x))]
    (reduce * num)))

CLOJURE MAP FILTER (15)

Map yapısı bir sekansın tüm ögelerine tek tek aynı işlemi yapmak için kullanılır.

(map (fn [x] (+ x 3)) '(1 2 3 4))

veya

bir sekansın şarta uyan ögelerini almak için

(filter even? '(1 2 3 4))

şeklinde kullanılabir

CLOJURE DOTIMES (14)

CLOJURE DOTIMES

Döngüler kurmanın diğer bir yolu ise dotimes’dır pratik bir for döngüsüne benzer

(defn pdotimes [fival]
  (dotimes [x fival]
    (println x)))
 
(pdotimes 5)

CLOJURE DOSEQ (13)

Sekansları daha işlemedik gerçi ama bir liste bir vektör veya kümeye sekans denir. Clojureda doseq makrosu ile sekanstaki her öge için geçerli olacak bir döngü kurulabilir.

(defn prnall [inseq]
  (doseq [value inseq]
    (println "a value" value)))
 
(prnall '(1 2 s e q "list"))

CLOJURE LOOP ve RECUR (12)

Clojure için for döngüsü yaratmak anlamsızdır o nedenle öz yinelemeli fonksiyonlar kunlanılır. Öz yinelemeli fonksiyonların tail olması beklenir. En sık metotlardan biri loop kullanmaktır

(defn factorial [x]
  (loop [i x fact 1]
    (if (= i 1)
      fact
      (recur (dec i) (* fact i)))))
 
(factorial 5)

Recur yapısı tail olan bir fonksiyona öz yineleme sağlar yukarıdaki faktöriel örneğinde tail bir fonksiyon yaratılmamış tail fonksiyon ifadeleri loop ile oluşmuştur.

Loop bind listesi şu anlama gelir.

[mevcut-dongu mevcut-dongunun-ilk-degeri tail-geri-donus-degeri tail-geri-donusun-ilk-degeri]

CLOJURE WHILE (11)

Clojure ortamı fonksiyonel programla dillerinin hepsinde olduğu gibi döngüye izin vermez ama döngü yaratmaya yarayan özyinelemeli makrolar vardır. Bu makroya while denilmektedir.

(def x 10)
 
(while (pos? x)
  (do (println x)
    (def x (- x 1))))

şeklinde kullanılır.

Sonraki sayfa →