• oncelikle: fonksiyonel programlama, zannedilebilecegi gibi "islevsel programlama" degil fonksiyon tabanli programlamaya yakin bir kavramdir.

    fonksiyonel programlama dilleriyle yapilir ama bu ayrim gunumuzde hem imperatif/nesne yonelimli dillere fonksiyonel ozellikler eklenmesiyle (bkz: linq), hem de fonksiyonel programlama dillerine nesne yonelimli ve imperatif ozellikler eklenmesiyle (bkz: f#) pek kalmamistir.

    fonksiyonel programlama disiplini yazilimi modellerken yazilimin fonksiyonlardan olstugunu temel alir ve veri yapilarinin icerigini degistirmek yerine onlardan yeni veri yapilari tureten fonksiyonlar hayal eder. tasarim ve gelistirme sureci bu kafayla isler.

    bu yuzden bildigimiz icini degistirdigimiz degisken kavrami fonksiyonel programlamada varolsa bile kullanimindan mumkun oldugunca kacinilir. zira bu degisken orucunun en buyuk avantaji programin state konusundaki cakismalarini minimize etmeyi saglamasi ve multi threading gibi isleri cakismalardan kacinarak cok kolay sekilde yapabiliyor olmasidir.

    tarihteki ilk fonksiyonel programlama dili lisp'tir. gunumuzdeki populer ornekleri ise ocaml ve haskell'dir. python/ruby gibi diller de fonksiyonel yapilari destekliyor olabilirler ama onlar hakkinda cok bilgim yok.

    ayrica .net dunyasindaki gelecek vaadeden dil ise ocaml'dan turemis olan f#'tir.

    (bkz: yapisal programlama)
    (bkz: nesne yonelimli programlama)
    (bkz: generic programming)
  • örnek olması açısından...

    c'de yazacağımız aşağıdaki fonsiyon ile

    double ortalama (double a, double b)
    {
    double toplam = a + b;
    return toplam / 2;
    }

    ocaml'da yazacağımız aşağıdaki fonksiyon aynı şekilde çalışır...

    let ortalama a b =
    let toplam = a +. b in
    toplam /. 2.0;;

    c'deki toplam değişken, ocaml'daki toplam ise ortalama fonksiyonunun içinde tanımlanmış başka bir fonksiyondur.
  • (bkz: lisp)
    (bkz: scheme)
    (bkz: ml)
    (bkz: caml)
  • cozulmek istenen problemin uygulama detaylarina odaklanmak yerine (imperative diller genelde gelistiriciyi bunun icin zorlar) siradan detaylari ve sik karsilasilan problemler icin can sikici uygulama ayrintilarini elemine ederek gelistiriciye sadece problemin cozumune ve problemin ozune odaklanmasi icin bir alan saglar.

    gelecegin paradigmasi olarak dillendirilse de asil odaklanmasi gereken sey paradigm shift degil programlama dillerinin daha ust seviye dillere evrilme surecidir. demek istedigim sey ileride cok iyi bir sekilde soyutlanmis ust seviye bir object-oriented programming dili ile de bir fonksiyonel programlama dili kadar efektif ve temiz kod yazabilecek olmamiz. hatta bu yaklasimi multi-paradigm olan scala dilinde gorebilirsiniz. java ile ayrintilarla bogularak yazacaginiz bir data class scala ile daha temiz ve ozlu yazilabilmekte. python 3 ile birlikte gelen data class ozelliginin de sizin yerinize uygulama ayrintilarini ele alarak sizin sadece problemin cozumune odaklanmanizi saglamakta.

    (bkz: clojure)
    (bkz: scala)
    (bkz: haskell)
  • bir oop değildir çünkü oop değildir. oop ve fp tamamen bir birlerinden farklıdır. oop veya fp tercih etmek tamamen öznel bir tercih meselesidir. ön görmesi çok da güç değil aslında bakarsanız ama ileride oop değil fp biliyor musun diye sorarlar adama o zaman bir oop değildir diyen arkadaşları sahneye alıp mikrofon vermek istiyorum . bir ne değildir ?
  • javascript üzerinden öğrenmek isteyenlerin reginald braithwaite'ın "javascript allongé" kitabını okuyabileceği programlama paradigması.

    öğrendiğinizde kod yazma biçiminizde gözle görülür bir değişiklik oluyor.
  • (bkz: erlang)
    (bkz: elixir)
  • fonksiyonel programlama, adı üzerinde işlemlerin çoğunun fonksiyonlara dayandırılarak yapılmasıdır.

    bir örnek yapalım. bu örneği önce prosedürel programlama yöntemine göre daha sonra da fonksiyonel programlama yöntemine göre yapalım.

    örneğin, bizden 1'den 1000'e kadar olan sayılardan hangilerinin mükemmel sayı olduğunu bulan bir program yazmamız istendi. mükemmel bir sayı, kendisini tam bölen sayıların toplamına eşit olan sayıdır. 6, mükemmel bir sayıdır çünkü 6'yı tam bölen sayıların (1, 2, 3) toplamı yine 6'dır.

    şimdi gelin, prosedürel yöntemle 1'den 1000'e kadar olan sayılardan mükemmel olanlarını bulan bir fonksiyon yazalım:

    --- spoiler ---
    def mukemmel_mi(sayi):
    mukemmel_sayilar = []
    for i in range(1, sayi):
    toplam = 0
    for j in range(1, i):
    if i % j == 0:
    toplam += j
    if toplam == i:
    mukemmel_sayilar.append(i)
    return mukemmel_sayilar

    print(mukemmel_mi(1000))
    --- spoiler ---

    izninizle, bu yukarıdaki kodları satır satır açıklamak istiyorum:

    1. "def mukemmel_mi(sayi):" ifadesi, fonksiyonumuzun adının "mukemmel_mi" olduğu ve bu fonksiyonun "sayi" isimli bir parametresi olduğu anlamına geliyor.

    2. "mukemmel_sayilar = []" ifadesi, yapılacak işlemlerden sonra mukemmel sayıları depolamak üzere kullanacağımız boş bir liste tanımladığımız anlamına geliyor. bu listenin ismi "mukemmel_sayilar".

    3. "for i in range(1, sayi):" ifadesi, "1" sayısından, "sayi" sayısına kadar her bir eleman için anlamına geliyor. "for" bir döngüdür, "i" ise "1" ile "sayi" arasında kalan her bir sayıyı temsil eder.

    4. "toplam = 0" ifadesi, "1" sayısından, "sayi" sayısına kadar olan her bir eleman için değeri "0" olan ve ismi "toplam" olan bir değişken tanımladığımız anlamına geliyor.

    5. "for j in range(1, i):" ifadesi ise, daha iç kısımda bulunan bir "for" döngüsüdür. yani bu "for" döngüsü, dıştaki "for" döngüsü blokunun altında çalışır. burada döngü aralığı "1" ile "i" sayısı arasındadır ve bu sayılar arasında kalan her sayı "j" ismiyle temsil edilir.

    6. "if i % j == 0:" ifadesi, eğer "i" sayısının "j" sayısına bölümünden kalan "0" ise anlamına geliyor.

    7. "toplam += j" ifadesi, şayet yukarıdaki koşul sağlanırsa, "toplam" isimli değişkene "j" sayısının ekleneceği anlamına geliyor.

    8. "if toplam == i:" ifadesi, içteki "for" döngüsünün dışında kalan bir ifadedir ama halen dıştaki "for" döngüsü blokunun içinde kalır. bu ifadeden, eğer "toplam" sayısı, "i" sayısına eşitse anlamı çıkar.

    9. "mukemmel_sayilar.append(i)" ifadesi, şayet yukarıdaki koşul sağlanırsa, "mukemmel_sayilar" listesine "i" sayısının ekleneceği anlamına geliyor.

    10. "return mukemmel_sayilar" ifadesi, dıştaki "for" blokunun da dışındadır. ve "mukemmel_sayilar" listesinin geri döndürüleceği anlamına geliyor.

    11. "print(mukemmel_mi(1000))" ifadesinde ise, "mukemmel_mi" fonksiyonu, parametre değeri "1000" yazılarak çağrılır ve bu fonksiyondan geri dönen değer (yani "mukemmel_sayilar" listesi) ekrana yazdırılır.

    bu yukarıda bahsettiğim işlemler, 1'den 1000'e kadar olan sayılardan hangilerinin mükemmel sayı olduklarını prosedürel yönteme göre bulur. şimdi gelin aynı sonucu alabileceğimiz bir fonksiyonel programlama örneği yapalım:

    --- spoiler ---
    mukemmel_mi = lambda sayi: list(filter(lambda x: sum(filter(lambda y: x % y == 0, range(1, x))) == x, range(1, sayi)))

    print(mukemmel_mi(sayi=1000))
    --- spoiler ---

    bu yukarıdaki kodlar, bir önceki prosedürel yöntemle yazılmış kodlarla aynı işlemi yapar. şimdi izninizle bu kodları soldan sağa doğru biraz açıklamaya çalışayım.

    1. ismi "mukemmel_mi" olan bir "lambda" fonksiyonumuz var.

    2. bu "lambda" fonksiyonunun parametresinin ismi "sayi".

    3. bu fonksiyon tipi liste olan bir veriyi geri almamızı sağlıyor. aşağıdaki kodların tamamı listemize ait. ancak biz sağa doğru kodları açıklamaya devam edelim.

    list(filter(lambda x: sum(filter(lambda y: x % y == 0, range(1, x))) == x, range(1, sayi)))

    4. "list"'in yanındaki "filter" bir fonksiyondur. kullanımı "filter(fonksiyon, dizi)" şeklindedir. yani "filter" fonksiyonunun ilk parametresi bir fonksiyon, ikinci argümanı ise bir dizidir. peki "filter" fonksiyonun ilk argümanı neye benziyor onu göstereyim.

    lambda x: sum(filter(lambda y: x % y == 0, range(1, x))) == x

    yukarıdaki ifade "lambda" fonksiyonuna aittir.

    5. "lambda" fonksiyonunun parametresi "x" sayısıdır.

    6. "sum", sayılardan oluşan bir dizideki elemanların toplanmasına yarayan bir fonksiyondur. "sum" fonksiyonunun başlangıç ve bitiş yerleri aşağıda gösterildiği gibidir:

    sum(filter(lambda y: x % y == 0, range(1, x)))

    7. "sum" fonksiyonu nasıl bir dizideki elemanları toplamaya çalışıyormuş bakalım. yine "filter" isimli bir fonksiyonla karşılaşıyoruz. ve "filter" fonksiyonunun başlangıç ve bitiş yerleri şöyledir:

    filter(lambda y: x % y == 0, range(1, x))

    8. dördüncü maddede bahsedildiği gibi, "filter" fonksiyonunun ilk parametresi bir fonksiyon, ikinci parametresi ise bir dizidir. "filter" fonksiyonun ilk parametresine bakalım:

    lambda y: x % y == 0

    "filter" fonksiyonunun ikinci parametresi ise şöyledir:

    range(1, x)

    9. demek ki, parametresi "y" olan bir "lambda fonksiyonumuz var ve bu fonksiyonun içindeki işlem ise şöyle bir işlemdir:

    x % y == 0

    10. bu yukarıdaki işlem eğer "x" sayısının "y" sayısına bölümünden kalan "0" ise anlamına geliyor. peki burada "y" sayısı nereden elde ediliyor bakalım. az önce "filter" fonksiyonunun ikinci parametresinin bir dizi olduğundan bahsetmiştik. işte "y" sayısı bu "range(1, x)" dizisinden gelir ve "1" ile "x" sayısı arasında kalan her sayıyı temsil etmek için kullanılır.

    11. "filter" fonksiyonunun burada yaptığı şey nedir ona bakalım.

    filter(lambda y: x % y == 0, range(1, x))

    yukarıdaki ifadeye göre, "1" ile "x" sayısı arasında kalan sayılardan "x" sayısını tam bölen "y" sayıları filtrelensin anlamı çıkar.

    12. "sum" fonksiyonuna bir daha bakalım:

    sum(filter(lambda y: x % y == 0, range(1, x)))

    yukarıdaki ifadeye göre, "1" ile "x" sayısı arasında kalan sayılardan "x" sayısını tam bölen "y" sayıları filtrelensin ve bu sayılar toplansın anlamı çıkar.

    13. şimdi gelin aşağıdaki ifadenin ne anlama geldiğini açıklayalım:

    lambda x: sum(filter(lambda y: x % y == 0, range(1, x))) == x

    yukarıdaki ifadeye göre, "1" ile "x" sayısı arasında kalan sayılardan "x" sayısını tam bölen "y" sayıları filtrelensin ve bu filtrelenen sayıların toplamı şayet "x" sayısına eşitse anlamı çıkar.

    14. şimdi ise kodun diğer kalan kısımlarını açıklamaya çalışayım:

    list(filter(lambda x: sum(filter(lambda y: x % y == 0, range(1, x))) == x, range(1, sayi)))

    yukarıdaki ifadeye göre, "1" ile "sayi" arasındaki her bir "x" sayısı için, "1" ile "x" sayısı arasında kalan sayılardan "x" sayısını tam bölen "y" sayıları filtrelensin ve bu filtrelenen sayıların toplamı şayet "x" sayısına eşitse bir filtreleme işlemi daha yapılsın ve bu filtrelenmiş sayılar liste içerisine alınsın anlamı çıkar.

    15. ve son olarak "mukemmel_mi" fonksiyonu parametre kısmına "1000" yazılarak çağrılır ve elde edilecek liste tipindeki veri "print" fonksiyonu ile ekrana yazdırılır.

    sonuç:

    fonksiyonel programlamada gördüğünüz gibi, bir çok işlem için fonksiyonlar kullanılırken, prosedürel programlamada "for" döngüleri, "if" koşul ifadeleri kullanılıyor. her iki fonksiyonun da bize vereceği değerler şöyle olacaktır:

    [6, 28, 496]

    demek ki, 1 ile 1000 arasında 3 tane mükemmel sayı varmış.

    yukarıdaki fonksiyonel programlama örneğinde 3 adet "lambda" fonksiyonu var. her bir "lambda" fonksiyonunun da 1 tane parametresi var. bu parametrelerin geçerli olduğu aralığı görmek için aşağıdaki resmi inceleyiniz.

    https://eksiup.com/images/64/23/vf107408buqmrr.jpg
  • günümüzde önemi anlaşılmaya başlanan bir yazılım tekniğidir. yazılım tasarımını nesneler ile değilde fonksiyonlar ile yapar. yazılan fonksiyonları pure function tarzı ile tasarlamaya çalışır. bu sayede de side effect den kaçınmaya çalışılır. fonksiyonel programlamada bir diğer önemli konu ise fonksiyon tasarımı döngüler içerisinde dönen komutlar ile basamak basamak yapılmaz, sadece matematiksel bir yaklaşımla formülize edilir. önemli dillerinden bazıları ise f# ve haskell dilleridir.
    (bkz: fonksiyonel programlama dili)
  • (bkz: scala)
hesabın var mı? giriş yap