Photo by Daniel Tong on Unsplash

JS ILE FONKSIYONEL PROGRAMLAMA

Object-Oriented Programlamanın Unutulmuş Tarihi — 5

Object Oriented Programlama acaba ilk başta bu programlama paradigmasını kuran kişilerin kafasında ki yapımı, yoksa şu anda bambaşka bir şekilde anlaşılmış farklı bir şekilde OOP uygulanıyor. Acaba Java, C++ veya .NET Object Oriented Programlamayı farklı mı yorumladılar ?

--

Bu yazıyı daha önceden yazmış olduğum Object-Oriented Programlamanın Unutulmuş Tarihi-1 , Tarihi-2, Tarihi3 ve Tarihi4 yazılarının devamıdır.

Not: Eric Elliott, kitabından okuduğum The Forgotten History of OOP blog yazısı Object Oriented nasıl bir düşünce yapısı ile ortaya çıktığı nasıl başka konulara ve önceliklere evrildiği açısından beni etkiledi. Bu yüzden bu blog yazısını çevirerek anlatmaya çalışacağım, tabi araya kendi notlarımı da ekliyorum 😃.

Daha önceden Java or C# ağırlıklı yazılım geliştirmişseniz. Nesne-Tabanlı(Object-Oriented) Programlama için temel kavramların aşağıdaki kavramlar olduğunu düşünürsünüz

  • Statik Type kullanımı
  • Polymorphism
  • Inheritance

Fakat Alan Kay programı matematiksel, cebirsel bir denkleme benzetip bu aksiyomlar üzerinden uğraşmanın,cebirsel(algebraic) formdaki genel yaklaşımlar ile uğraşmak gerektiğini düşünüyordu. Örneğin;

Haskell

fmap :: (a -> b) -> f a -> f b

Yukarıdaki tanımlama Haskell Functor Map yapısı , Functor kavramı map edilebilir anlamında yapılar için kullanılıyor. Örneğin JS array’de bulunan [].map() gibi. Burda map statik bir tür ihtiyacı duymadan bir veri yapısının içerisindeki değerlere bir fonksiyon etkisi oluşturup başka bir değere dönüştürüyor.

Bu Map Functor yeteneğini Örneğin Frontend Development sırasında sunucudan elde ettiğimiz JSON nesnelerini → JSX React Element dönüştürürken sıkça kullanıyoruz.

Not: Bu konu da daha fazla bilgi edinmek için daha önceden yazmış olduğum aşağıdaki yazıları okumanızı öneririm.

JavaScript

Aşağıdaki JavaScript örneğinde de array içerisinde bulunan değerler çift sayımı(2'ye bölünebiliyor mu) yoksa tek mi sorunun cevabını oluşturup başka bir array içerisinde bunun cevaplarını yazmasını istiyoruz.

Burda verdiğimiz array içerisindeki değerler number, sonuç array içerisindeki değerler ise boolean

// isEven = Number => Boolean
const isEven = n => n % 2 === 0;
const nums = [1, 2, 3, 4, 5, 6];// map takes a function `a => b` and an array of `a`s (via `this`)
// and returns an array of `b`s.
// in this case, `a` is `Number` and `b` is `Boolean`
const results = nums.map(isEven);console.log(results);// [false, true, false, true, false, true]

Yani map fonksiyonu bu algoritmayı çalıştırırken kendisini array ile soyutlamıştır. Array içerisinde tutulan değer ile ilgilenmemektedir. Array içerisinde başka bir tür olması map fonksiyonunu etkileMemektedir. Bu değerleri işleyecek olan f fonksiyonu farklı olacaktır.

[1, 2, 3, 4, 5, 6] -> f -> [false, true, false, true, false, true]

Örneğin bu array içerisinde haftanın günleri olsaydı, fonksiyonda örneğin isWorkingDay olsaydı, map fonksiyonunu değiştirmemiz gerekir miydi? Cevap hayır. İşte generic type sağlamış olduğu bu tür avantajlar bulunur.

.map () genel type çalışma işlevini iyi işletir çünkü diziler(array), cebirsel(algebraic) functor yasalarını uygulayan veri yapılarıdır.

Type(Veri Türleri) .map () için önemli değildir çünkü onları doğrudan değiştirmeye çalışmaz, bunun yerine uygulama için doğru türleri bekleyen ve döndüren bir fonksiyonları uygular.

// matches = a => Boolean
// here, `a` can be any comparable type
const matches = control => input => input === control;
const strings = ['foo', 'bar', 'baz'];
const results = strings.map(matches('bar'));
console.log(results);
// [false, true, false]

Bu genel tür ilişkisinin TypeScript gibi bir dil ile doğru ve kapsamlı bir şekilde ifade edilmesi zordur. Ama Haskell’de Hindley Milner Tür Sistemi daha yüksek türler desteğiyle ifade edilmesi oldukça kolaydır.

Not: Bu blog yazıldıktan sonra TypeScript birçok güncelleme geldi. Burada anlatılan TypeScript ve Hindley Milner Type System arasında temel farkların ne olduğunu henüz tam anlamış değilim. İlerleyen yazılarda TypeScript konularında belki bu kısma biraz daha detaylı değiniriz.

Çoğu Tür Sistemi (Type System) aşağıdaki bir çok konunun tasarımında ve gerçekleştiriminde ciddi sınırlandırmalar getirir.

  • özgür dinamik tanımlamalar (free expression of dynamic),
  • fonksiyonel fikirler (functional ideas),
  • fonksiyonel kapsamaları (function composition),
  • object kapsamaları (free object composition),
  • runtime object extension,
  • combinators,
  • lenses, etc,

Diğer bir deyişle Type Sistemleri Composable Software yazmayı zorlaştırır.

Eric Eliotta göre

“Tür sisteminiz çok kısıtlayıcıysa (ör. TypeScript, Java), aynı hedefleri gerçekleştirmek için daha fazla dolambaçlı kod yazmak zorunda kalırsınız. Bu, statik türlerin kötü bir fikir olduğu veya tüm statik tür uygulamalarının eşit derecede kısıtlayıcı olduğu anlamına gelmez.(Örn Hindley Milner Type System)”

  • Statik Type kullanıyor ve seviyorsanız, bunların fanı iseniz,
  • Static Type kısıtlamalarına aldırış etmiyorsanız,
  • Bu yazıdaki cebirsel düşünmek ve genelleştirmeyi zor buluyorsanız,

Bu yukarıdaki fikirlerin uygulanabilirliğinden çok Type System sizi sınırlandımasından kaynaklıdır. Daha özgür ve dinamik kodlama için daha fazla serbestlik derecesine sahip araçlara ihtiyacınız var. Sizi sınırlandırma ması gerekiyor.

Kendi Düşüncelerim: Burda benim görüşüm ise, TypeScript ve Type sistemleri özellikle Enterprise(Kurumsal) büyük projeler geliştirirken birçok kişinin beraber çalıştığı, modüllerin kendi içerisinde birbirini kullandığı, FE ve BE entegrasyonlarının olduğu yerlerde Type Sistemlerinin sınırlandırmaları ürünün sağlıklı gelişip büyüyebilmesi için önem teşkil ediyor.

Bu yüzden öncelikle çok dinamik olmak isteyip, istemediğinize karar vermeniz daha önemli.

İkinci bir nokta Java, C++ Object Oriented yaklaşımları anlamak çok çok daha basit, öğrenme eğrisi ve düşünme şekli insan aklına daha yatıyor. Fonksiyonel Programlada bu matematiksel ve cebir düşünce tarzı herkesi kolay bir şekilde algılayıp uygulayabileceği kavramlar değil. Biraz matematik background(altyapısı) ile programlamaya başlamak lazım.

Referanslar

Okumaya Devam Et 😃

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

--

--