C# İle Fonksiyonel Programlama - Currying ve Kısmî Fonksiyonlar

Giriş

Serinin son yazısında, currying metodundan ve C# ile nasıl implemente edileceğinden bahsedeceğiz.

Currying, birden fazla parametre alan bir fonksiyonun, tek parametre alan fonksiyona dönüştürülmesi işlemidir.

İhtiyacımız, serinin ilk yazısından da hatırlayacağınız üzere fonksiyonel programlamanın temellerinden “fonksiyonların fonksiyon döndürebilmesi”.

Lise Matematik Bilgilerimizi Hatırlayalım

Matematik fonksiyonları ile currying yöntemini açıklamak çok daha kolay. Elimizde x ve y parametreleri alan bir f(x,y) fonksiyonumuz olsun.

f(x,y) = x2 + y2

Bu fonksiyonu çağırabilmek için x ve y olarak iki farklı parametre göndermemiz gerekiyor.

f(3, 4) = 32 + 42 = 25

  • Bu fonkiyonu curry işlemine soktuğumuzda, sadece x parametresi alan yeni bir fonksiyon dönmeli,
  • Dönen bu fonksiyona x için 3 değerini verdiğimizde, y parametresi alan ikinci bir fonksiyon dönmeli,
  • Bu ikinci fonsiyona y için 4 değerini verdiğimizde nihayet 25 sonucunu vermelidir.

Kısmî Fonksiyon Nedir?

Kısmî (partial) fonksiyon, parametrelerin bazılarının metoda daha sonra geçilebildiği fonksiyonlardır.

Beş parametreli bir fonksiyonun ilk parametresini şimdi, kalan dört parametreyi daha sonra geçebilmek için Func delegesini kullanacağız.

Curried Fonksiyon

Curried fonksiyonlar kısmî fonksiyonların özel bir türüdür. Dönüştürülen fonksiyonlar daima tek parametre aldığında curried, birden fazla parametre aldığında ise partial olarak adlandırılır.

C# İle Basit Bir Currying Uygulaması

Elimizde farazi bir KDV hesaplama fonksiyonu olsun.

calculateTax

Bu fonksiyonun imzası aşağıdaki şekilde olur:

calculateTax

Yukarıda, iki parametreli bu fonksiyonun iki dönüşüm geçirerek, iki adet ara fonksiyonun oluşacağını belirtmiştik. Diğer ifadeyle 25 sonucuna ulaşabilmek için fonksiyonumuz iki currying aşamasından geçecek.

curried

Curried bir fonksiyonun kullanımı aşağıda şekilde.

curried

Neden Böyle Bir Kullanıma İhtiyacımız olsun?

calculateTax(500.00, 0.18) varken neden curried(500.00)(0.18) şeklinde bir kullanıma ihtiyacımız olsun?

Genel amaçlı bir fonksiyondan, yeni fonksiyonlar türeterek özel amaçlar için benzer fonksiyonlar tekrarlarının önüne geçerek kod kalitesini artırmak için.

Currying Olmadan

without currying

Currying Kullanarak

curry in action

Daha fazla kod yazdık, fakat aşağıdaki fonksiyonların tekrar kullanılabilir olduklarına dikkat edin:

  • taxCalculator
  • taxCalculatorFor500

taxCalculator genel amaçlı, taxCalculatorFor500 ise özel amaçlı türetilmiş bir fonksiyondur. Yaptığımız işlem, fonksiyonun ilk parametresi 500.00 değerini önceden geçerek kısmî bir fonksiyon türetmek.

Devletimiz, yeni bir vergi çıkardığında tek yapmamız gereken, taxCalculatorFor500 fonksiyonunu vergi oranı ile çağırarak yeni vergi tutarını hesaplamak olacak.

İki Parametreli Bir Fonksiyon İçin Jenerik Curry Fonksiyonu

Aşağıdaki kodu language-ext 1 kütüphanesinden aldım. 10 parametreli bir fonksiyon için curry ihtiyacınız olursa 115. satıra bakabilirsiniz.

curry

Sonuç

Kısmî fonksiyonlar için language-ext kütüphanesinin wiki sayfasını 2 okumanızı tavsiye ederim. Tüm design pattern için geçerli olduğu gibi, currying ve partial functions patternlerini uygulayacağınız yerleri iyice düşünmelisiniz.


  1. Language-Ext, Haskell fonksiyonel yöntemlerini C#‘a uyarlayan ilginç bir kütüphane. ↩︎

  2. Thinking Functionally: Partial application ↩︎