JS ILE FONKSIYONEL PROGRAMLAMA

Saf (Pure) Fonksiyon Nedir?

Fonksiyonel Programlamanın temellerini oluşturan konulardan biriside Saf(pure) fonksiyonlardır. Bu yazıda fonksiyon türleri ve nasıl pure fonksiyon yazabileceğiniz üzerinde duracağım.

3 min readFeb 3, 2020

--

Bu yazıyı daha önceden yazmış olduğum JS ile Fonksiyonel Programlama yazısının bir devamı olarak yazıyorum. Bir çok kavramı tek bir yazıda ele almanın yaratacağı karmaşıklıktan kaçmak için bu şekilde bir yönteme başvurdum.

Saf(pure) fonksiyonlar, fonksiyonel programlamada önemli bir yer teşkil eder, Concurrency (eş-zamanlılık), Test edilebilir kod, tahmin edilebilir kod, deterministik bir kod geliştirmek için pure fonksiyonlar oluşturmanız gerekir.

Fonksiyon belli girdiler alıp, bu işletip sonuç dönen mekanizmalardır ve 3 amaç için kullanılırlar.

Mapping: Fonksiyona giren girdileri sonuçlara map eder. Bu bizim bildiğimiz f(x)=y işlemidir.

Procedures: Ardaşık instruction/komutları çağırdığımız fonksiyonlar.

I/O: Network işlemleri, Kullanıcı girdileri yakalama, ekrana çizim, console log yazdırma, dosya sistemine erişim vb..

Pure Function Nedir?

  • Aynı girdiler için her zaman aynı sonucu verecek.
  • Herhangi bir side effect (yan etkisi) olmayan

fonksiyona Pure(Saf) fonksiyon denir ve Mapping işlemleri Pure fonksiyon şeklinde yazılabilir. Algebra işlemlerinde ilgili fonksiyonun karşılığında bir değer koyabiliyorsanız Örneğin max →12 , double →6 değeri koyabilirsiniz. Bunu fonksiyon bu aşamada herhangi bir console, ekran, network işlemi yapmadığı için ve sonuç ne olursa olsun aynı olacağı için diyebilirsiniz.

//Max
const max=Math.max;
console.log(max(3,2,8,12));
console.log(12)
//Double
const double=x=>x*2;
console.log(double(3));
console.log(6)

Bu şekilde programın sonucunu değiştirmeden yerine eşdeğer değerine koyma işlemine referential transparency denir.

Pure fonksiyonlar paralel programlama için çok uygun mekanizmalardır. State tutmadıkları ve dış etkileri olmadıkları için paralel olarak rahat bir şekilde işletilebilirler.

Bir bağımlılıkları olmadığı için kod içerisinde organize edilmeleri, refactor ile bir yerden başka bir yere taşınmaları oldukça kolaydır. Bakım aşamasındaki değişikliklerden az etkilenirler.

Bu yazıda Mapping fonksiyonları üzerinde duracağız. Mapping fonksiyonlarının Pure fonksiyon olmasındaki zorluklar nelerdir dersek

  • Ortak Durum Paylaşımı (Shared State)
  • Random ve Date gibi aynı değeri oluşturmayan fonksiyonların kullanımı
  • Mutability

Problemler

Ortak Durum Paylaşımı (Shared State)

Aynı veri üzerine birden fazla process yazıyorsa burda ortak durum paylaşımı olur. Örneğin AJAX call düşünelim. Arama yaparken 3 karakterden sonra arama işlemi başlatılsın. 3 karakter ayrı bir arama isteği, 4ncü karakterde ayrı bir arama isteği, 5 karakter yazıldığımda ayrı bir arama AJAX request yapılsın.

4ncü karakterin response diğerlerinden sonra/geç geldiğini düşünelim. Bu durumda sistem 5 karakterin aramanın sonucunu değilde 4 karakter aramanın yanıtını sisteme yansıtacak buda hatalı bir gösterim olacaktır. Bunu engellemek için Redux’ta olduğu gibi veri üzerinde bir karar mekanizması olup bunun 3,4 aramanın yanıtlarını iptal et çünkü 5 için arama yapacağına bunun yanıtının sistem için anlamlı olması sağlanır.

Paralel işleme sırasında bir durum oluşturuluyorsa bu deterministik olmayan sonuçların ortaya çıkmasına sebep olur.

non-determinism = parallel processing + mutable state(değişken durum)

JS Single Thread yapıda olduğu için bu şekilde paralel processing işlemi olmaz şeklinde düşünceleriniz olabilir ama EventLoop yazımda belirttiğim gibi WebAPI, CallbackQueue, Timeout, NodeJS için( Internal C++ thread-pool) gibi mekanizmalar ile JS nasıl paralel bir şekilde çalıştığını anlatmıştım.

Bu tarz paralel işleyen yapıların mutable(değişken) state üretmesi sonucunda beklenmedik sonuçlar ile karşılaşabilirsiniz.

Fonksiyona Giren Girdiler Aynı Sonucu Vermez İse?

Bu durum fonksiyonun içerisinde her çağrıldığında başka değerler üreten aşağıdaki fonksiyonlar varsa ve bunlar sonuç üzerinde etkiliyse her fonksiyon çağırdığınızda farklı bir sonuç ile karşılaşırsınız.

  • fonksiyon içerisinde Math.random() değer üretiliyorsa
  • new Date() zaman değeri üretiliyorsa

Fonksiyon Yan Etkisi Var İse

Geliştirdiğiniz fonksiyon parametre olarak verdiğiniz değeri değiştiriyorsa bunun çok sakıncası vardır. Dışarıda bir state olarak tanımladığınız user nesnesinin nerde hangi fonksiyonun içerisinde nerde değiştirildiğini bilemezsiniz.

const addAge=(user,age)=>{user.age=age; return user;};
const user={name:'onur'}
console.log(addAge(user,12));
const addElement=(arr,el)=>{arr.push(el); return arr};
const arr=[1,2,3];
console.log(addElement(arr,5));

Bundan dolayı state mutable hale gelmiş. Fonksiyon içerisinde değerin immutable olması için. Nesneden yeni bir nesne türetmeniz gerekir. Burada deep copy(derin kopyalama) yöntemi nesnenin kopyası alınır. Not: Bunun yerine daha performanslı tries veri yapısını kullanan kütüphanelerden immutable.js veya Mori kullanabilirsiniz.

Referanslar

Okumaya Devam Et 😃

Bu yazının devamı veya yazı grubundaki diğer yazılara erişmek için bu linke tıklayabilirsiniz.

--

--