Birkaç yıldır mütemadiyen fonksiyonel programlama ile ilgileniyorum. Ancak bir süre öncesine kadar fonksiyonel programlamanın sunduğu asıl güç olan fonksiyonları alıp çeşitli şekillerde yeniden düzenleme konusuna pek hakim olamadığımı, o teknikleri çok fazla kullanamadığımı hissediyordum.
Önceleri bunun genelde ilgilendiğim konuların fonksiyonel programlamaya çok uygun olmamasından kaynaklandığını düşündüysem de zaman geçip bu alanda uğraşmaya devam ettikçe sorunun bu olmadığının farkına vardım. Sorunun kaynağı yazdığım fonksiyonların diğer fonksiyonlar ile düzgün bir biçimde birleştirilmeye pek müsait olmamasıydı. Bundan bir yıl önce yazdığım kodlara bakıyorum ve tam bir kontrol yapısı karmaşası görüyorum. İç içe geçmiş for/if yapıları vs... Daha önceden de sürekli duyup, bilip uygulamadığım bir yöntemin önemini bunn üzerine kavramış oldum. Bir fonksiyonun içerisinde, asla birden fazla kontrol/döngü yapısı bulunmaması gerekir
Eğer fonksiyonlarınız içerisinde birden fazla kontrol yapısı barındırmıyorsa (ve tabiiki fonksiyonel programlamanın soğasına uygun olarak state bağımsız ise) bu fonksiyonlar diğer fonksiyonlar ile birleştirilerek yeni fonksiyonlar ortaya çıkarabilirsiniz. Eğer programlama diliniz de bu tip işleri kolaylaştıran Haskell gibi bir dil ise şu gibi ilginç örnekler ortaya çıkabilir:
group :: Eq a => [a] -> [[a]] group = (flip group') [] group' :: Eq a => [a] -> [[a]] -> [[a]] group' [] y = y group' (x:xs) [] = group' xs [[x]] group' (x:xs) (z@(y:ys):zs) | x == y = group' xs $ (x:z):zs | otherwise = group' xs $ [x]:(z:zs) comparing :: Ord b => (a -> b) -> a -> a -> Ordering comparing p x y = compare (p x) (p y) maximumBy :: Ord a => (a -> a -> Ordering) -> [a] -> a maximumBy f (x:[]) = x maximumBy f (x:xs) = case (f x y) of LT -> y EQ -> x GT -> x where y = maximumBy f xs mostCommon :: Ord a => [a] -> a mostCommon = head . maximumBy (comparing length) . group . sort
Tabii yukarıdaki kod banim icadım değil, hatırlamadığım bir blogdan alıntı. Bu ve bunun kadar fantastik birçok kod örneği hergün Planet Haskell'de yayınlanıyor.
Burada dikkat çeken noktalar ne? Öncelikle şunu aklımızın bir köşesine koyalım. "." karakteri fonksiyon bileşke operatörüdür. Örneğin:group . sort = group(sort(x))
Yeri gelmişken bahsedilmeyi hak eden bir diğer güzel özellik ise "partial application". Bu ne demek? Partial application, fonksiyonların otomatik olarak "currying" işleminden geçmesidir. Bu sayede "+ 20" yazmamız + fonksiyonuna tek parametre için currying uygulamamız anlamına geliyor. Açıklamak gerekirse, + diğer birçok fonksiyondan hiçbir farkı olmayan bir fonksiyon. Bu fonksiyon iki parametre alıyor (ismi a ve b olsun). Biz bu fonksiyona parametrelerinden sadece birini (a'yı) verecek olursak elde edeceğimiz şey tek parametre (b) alan yeni bir fonksiyondur. Daha sonra bu fonksiyonu kullanarak istediğimiz herhangi bir b sayısını a ile toplamamız mümkün olur. İşte partial application denilen nimet, currying adlı işi otomatik olarak uygular ve bize bu fonksiyonu üretir.
Bugün yazdığım ikinci süper dağınık blog girdisi ile verdiğimiz rahatsızlıktan ötürü özür dileriz.