F# ile Fonksiyonel Programlama

fsharpF# öğrenmeye karar verdim.

Neden mi? Aslında bunun temel olarak 3 nedeni var;

  • Hayatımda hiçbir zaman fonksiyonel programlama temelinde bir dil öğrenmedim. Bunun nedeni de galiba OOP’nin günümüzde en popüler progrmalama paradigması olmasını gösterebilirim. Üniversite hayatım boyunca ve kısa süreli çalışma hayatım boyunca fonksiyonel programlamaya hiç ihtiyaç duymamam da buna neden oldu diyebilirim.
  • “Guru” olarak adlandırabileceğim birçok kişiden bu dili öğrenmenin ne kadar eğlenceli olduğunu, uygularken de bulmaca çözmek gibi bir his verdiğini duyunca açıkçası daha fazla dayanamadım. Adeta bir lezzetli çipetpet havası var F#’ta.
  • Yeni bir programlama dili öğrenmek ne zaman eğlenceli olmadı ki?

 

Kısaca Fonksiyonel Programlama

Fonksiyonel programlama, programları, argümanları ve dönüş değeri (return value) olan fonksiyonlar toplamı olarak görür. Nesneye yönelik programlamanın aksine, iteration işlemi için loop’lar kullanmak yerine çoğunlukla recursion kullanır. Program içerisindeki fonksiyonlar daha çok matematiksel fonksiyonlara benzerler zira programın durumunu değiştirmezler. Kısaca, bir değer bir identifier’a atandığında, asla değişmez. Fonksiyonlar parametre değerlerini değiştirmezler ve bu fonksiyonların sonuçları tamamen yeni bir değer döndürürler. Daha da kısaca, bir değer bir bellek bölgesine atandığında, asla değişmez. Fonksiyon sonuçları oluşturmak ise, önce fonksiyonlar değerleri kopyalar, bu kopyalanan değerleri değiştirerek işlem yaparlar. Orijinal değerleri başka fonksiyonlar kullanabilsin diye serbest bırakırlar ve artık onlara ihtiyaçları kalmadığında boşa çıkartırlar. Garbage Collection kavramının temelini oluşturur bu.

Bu sayede Fonksiyonel programlamanın birçok karmaşık hesaplama problemlerine çözümler sunduğu söylenir.

Fonksiyonel programlama ile ilgili birkaç kavramı da bilmek gerekiyor;

  • Higher order functions: Matematik ve genel bilgisayar bilim’inde bu fonksiyonlar en azından şu iki işlevden birini yapar;
    • Bir veya birden fazla fonksiyonu input alma veya
    • Output olarak bir fonksiyon verme. Diğer tüm fonksiyonlar first-order functions olarak isimlendirilir. Bu fonksiyonlara örnek olarak türev ve integral gösterilebilir. Zira ikisi de input olarak bir fonksiyon alıp geriye bir fonksiyon döndürürler. F# içerisinde bulunan List.map buna örnek olarak gösterilebilir.
  • First class functions: Bir elementin first class function olabilmesi için şunlardan biri olması gerekir;
    • Bir fonksiyona parametre olarak gönderilebilme
    • Fonksiyonlardan bir değer olarak dönebilme veya
    • Değişkenlere atanabilme. Programın herhangi bir yerinde bulunabilirler.
  • Pure functions: Bu fonksiyonlar şu iki maddeye birlikte sahiptirler;
    • Bu fonksiyonlar aynı input veya inputlarda aynı output’ları üretirler.
    • Bu fonksiyonların sonucu programda herhangi bir yan etkiye (side effect) neden olmazlar. (Mutable nesnelerin değişimi gibi veya I/O değişimi) Bu gibi fonksiyonlara örnek olarak Cos(x)  verilebilir.
  • Impure functions: Pure fonksiyonların tam tersi mantıkta çalışırlar. Örneğin;
    • Zamanı parametre alıp geriye haftanın günlerini döndüren bir fonksiyon. Zira farklı zamanlarda farklı değerler döndürebilir.
    • Random() fonksiyonu. Zira her çağırışımızda farklı bir değer döndürür. Ama Random(seed) fonksiyonu bir pure fonksiyondur. Zira bu fonksiyonu bu parametre ile her çağırışımızda aynı değer döndürür.
    • C’deki printf() fonksiyonu. Zira side effect olarak I/O’ya bir output verir.
  • Strict evaluation: Fonksiyonel programlama dilleri strict ve non-strict evaluation olarak kategorilendirilebilir. Temel konsept olarak fonksiyon argümanları nasıl işlenir ve expression’lar ne zaman hesaplanır kavramlarına dayanır bu kategorilendirme. Örneğin;
    • Strict evaluation altında
       print length([1+1, 2*2, 3/0, 4+4]) 

      kodu çalışmaz zira 3 / 0 division by zero döndürür. Fakat non-strict (lazy) evaluation altında bu geriye 4 sonucunu döndürür zira length içerisindeki expression’lar çalıştırılmaz. Sadece bunların uzunluğu bilgisi döndürülür. Strict evaluation altında bir fonksiyon çağırılmadan önce fonksiyonun tüm argümanları çalıştırılır.

Fonksiyonel programlamanın avantajlarını görmek için FP’nin yasakladıklarından çok, izin verdiği özelliklere bakılması gerektiği söylenilir. Örnek olarak fonksiyonel programlama ile fonksiyonlara bir değer gibi bakmak ve onları başka fonksiyonlara geçirmek. Bu başta pek önemli gözükmese de, etkileri olağanüstü olduğu söyleniyor. Data ve fonksiyonu birbirinden ayırmanın birçok problemin çözümüne olanak sağladığı söylenir. OOP programlamara göre FP programları daha kısa ve daha modülerdir.

Kısaca F#

F#’ın birçok sıkıntılı hesaplama problemlerini çözmek için en iyi yaklaşımlardan biri olduğu söyleniyor. F#, fonksiyonel programlama dışında imperative programming ve object-orianted yaklaşımlarına uyumluluk gösterir. Strongly typed özelliği mevcuttur, bu sayede programcıların belirsiz durumlar olmadığı sürece değişken tiplerini açıkça belirtmelerine gerek yoktur. C#’ta buna örnek olarak var keyword’ü gösterilebilir (tam karşılığı olmasa da). Bunun dışında inferred typing özelliğini de destekler.

F# bir “önce fonksiyon” (functional-first) dilidir. Buna rağmen az önce bahsettiğim gibi imperative programming ve object-orianted yaklaşımlarına da uyumluluk gösterdiğinden bu özellikler diğer Microsoft dillerine göre F#’ı daha esnek kılıyor.

F# temel olarak OCalm (object-orianted fonksiyonel programlama) dilinden modellendi. Ve .NET ile güçlendirildi. Generics kısmını hiçbir kod değiştirmeden destekler. Hatta IL (Intermediate Language) kodunu destekler. F# derleyicisi, sadece herhangi bir CLI (Common Language Infrastructure) için çalıştırılabilir dosyalar üretmez, ayrıca CLI olan her platformda çalışabilir. Bunun anlamı F# sadece Windows işletim sistemi ile sınırlı değildir. Ayrıca Linux ve Mac OS X üzerinde de çalışabilir.

Bu yazıdan yaklaşık bir ay önce OSS-approved license altında F# tamamen open source oldu. Microsoft tarafında, Visual Studio 2010, 2012 ve 2013 için tool’lar geliştiriliyor. Ayrıca F#’ın internet ortamında çok hareketli bir topluluğu mevcut. Birçok geniş ölçekli projelerde F# kullanarak katkıda bulunuyorlar. Birçok konferansta F# hakkında konuşmalar yapıyorlar. Twitter adreslerine şuradan ulaşabilirsiniz. Stack Overflow’da sorulara cevap veriyorlar. İnsanlara F# öğrenebilecekleri birçok eğitici site oluşturuyorlar.

F# Kurulumu

Yukarıda bahsettiğim gibi, F# birden fazla platformu destekler. Bu listeye buradan ulaşabilirsiniz.

Eğer windows üzerinde kullanıyorsanız, Visual Studio en iyi seçenek görünüyor. Visual Studio 2010 ve üzerinde F# default olarak kurulu olarak geliyor. Visual Studio 2008 kullanıyorsanız, MSDN üzerinden download edebilirsiniz. Eğer Vlsual Studio kullanmıyorsanız, Visual Studio Integrated Shell’i download edip, sonra F#’ı kurabilirsiniz. Temel olarak command-line compiler olan fsc.exe ve F# Interactive fsi.exe ihtiyaçlarınızı karşılayacaktır. Visual F# Resources sayfasından daha fazla bilgiye ulaşabilirsiniz.

Faydalı Linkler