Lisp ve JVM’in buluştuğu Clojure ile ne zamandan beri tanışmak istiyordum. Clojure, söylenenlere göre Lisp fanatiklerinin Lisp’de en sevdiği özelliklerin tutulduğu ve nefret edenlerinin en nefret ettiği parçaların çıkarıldığı bir programlama dili. Java sanal makinesi üzerinde çalıştığı için bütün Java kütüphanelerini kullanabiliyor, Java ve diğer JVM dilleriyle ortak kullanabileceği kod tabanları oluşturabiliyor. Kod yapısına baktığınızda direkt Lisp gibi görünse de parantez kullanımı biraz daha azaltılmış. Lisp yapısının haricinde dilin harika özellikleri var.

Fonksiyonel programlama son zamanlarda oldukça popüler. Fonksiyonel programlamada yazılım kalitesini arttıracak önemli konseptler ve yaklaşımlar bulunuyor. Zaman zaman bunları Ruby ve Python gibi dillere de uyarladığımız oluyor(immutable object vs). Ancak gerçek hayatta işler malesef tamamen fonksiyonel olmuyor. Zaten saf fonksiyonel programlama her problemin çözümü olsaydı bugün saf fonksiyonel bir dil olan Haskell gibi diller en yaygın dillerden olurdu. Scala, Erlang, F#, Groovy vs birçok fonksiyonel dilden Clojure seçmemdeki temel sebep Lisp mantığının hayat kolaylaştırıcı yönlerinin modern standartlarla buluşması ve fonksiyonel programlamanın gerçek hayat senaryolarına uygun olan yönlerini mantıklı bir şekilde harmanlaması oldu.

  • Lisp lehçesi olması
  • Fonksiyonel programlamanın iyi yönlerini alması
  • Thread-safe olması
  • Güçlü ve kolay kullanılan paralel programlama özellikleri olması
  • Büyük ve küçük ölçekli projelere uygun olması

Yukarıda saydığım özelliklerin büyük çoğunluğu kısmen veya tamamı birçok dilde zaten var. Ancak bütün bunların haricinde ben bilhassa o dilde kod yazarken aldığım zevke bakıyorum. Bu nedenle Clojure bana uzun süre arkadaşlık edecekmiş gibi duruyor.

Örn Java ile boş string testi yapmak için:

public class StringUtils {
  public static boolean isBlank(String str) {
    int strLen;
    if (str == null || (strLen = str.length()) == 0) {
      return true;
    }
    for (int i = 0; i < strLen; i++) {
      if ((Character.isWhitespace(str.charAt(i)) == false)) {
        return false;
      }
    }
    return true;
  }
}

Aynı kodun clojure ile yazılması:

(defn blank? [s] (every? #(Character/isWhitespace %) s))

Tek satırda işi bitirmek ne güzel değil mi? Özellikle farklı bir tarz syntax ile. :)

Herkesin bildiği üzere çok kod beraberinde daha çok hata ihtimali, daha uzun yazma süresi ve bakım konusunda daha büyük zorluklar getirir. Uzun lafın kısası çok kod eşittir çok maliyet. Aslında bu noktada Clojure, girişimlerin de seveceği bir programlama dili.

Öncelikle Clojure kullanmaya başlamak için Leiningen isim bir araç yükledim. Pek çok alternatifi olmasına rağmen en hoşuma giden bu oldu. Nedir diye sorarsanız Ruby’den bildiğimiz rake gibi bir komut satırı aracı. Terminal’e lein adında bir komut ekliyor. Aslında rake’den ziyade

  • rake
  • gem
  • rails (CLI olarak)
  • repl

gibi birçok aracım kullanışlı bir şekilde bir araya gelmesi diyebiliriz. Leiningen yüklemek için OS X kullanıyorsanız :

brew install leiningen

komutunu kullanabilirsiniz.

Daha sonra komut satırına

lein new helloapp
cd helloapp
find .

komutlarını girerek tipik bir leiningen projesinin yapısı görebilirsiniz.

lein help

komutu ile lein ile çalıştırabileceğiniz komutların listesini kontrol edebilirsiniz.

Bu noktada Lisp dünyasına ‘merhaba’ demek için

lein repl

komut satırında user=> promptunun olduğu satıra:

(println "Merhaba Dünya")

İşte bu kadar.