Kotlin Arrow Kütüphanesi Nedir? Neden Kullanmalıyız?

Mehmet Fethi Mese
Delivery Hero Tech Hub
4 min readSep 12, 2022

Kodları yazan kişiler yazılımcılar olarak bizleriz dolayısıyla insan faktörü olan her yerde hata yapma olasılığı var demektir. Bu nedenle en güvendiğimiz kodlarımızda bile hata olabilecek durumlar oluşabilmektedir. Fonksiyon içerisinde connection hatası, query hatası veya beklenmeyen bir json hatası almamız muhtemeldir. Bu hataları gidermek için kullanılan en yaygın yöntem exception fırlatmaktır. Fakat bu exception’lar her durumda izlenebilir değildir veya compiler tarafından belirli bir forma dönüştürülememektedir.

Uygulamamızda herhangi bir exception aldığımızda, ne tür bir exception almışız ve nereden almışız şeklinde kod içerisinde aramalara başlarız. Bu hataları giderebilmek içinse tüm exception’ları yakaladığımızdan emin olmamız gerekmektedir. Bazen benzer exception’lar bir kaç farklı yerden gelebilmektedir. Bu durumda gerçekte nereden hata aldığımızı kestirmek daha da zor olmaktadır. Peki bu tür hata durumlarını nasıl çözeriz veya nasıl minimize edebiliriz? Şimdi gelin bu sorunları referans alarak çözüm sunan Arrow kütüphanesini birlikte inceleyelim.

Arrow kütüphanesi Kotlin ile uyumlu bir şekilde çalışabilen bir araç kitidir. Arrow, Kotlin içerisinde railway paternini kullanarak fonksiyonel programlama yazmamızı sağlamaktadır. Peki nedir railway paterni? Railway paterni, iş akışımızda her şey doğru gittiğinde ilgili sonucu dönen ama hata alınan ilk durumda ise akışı durdurup hatayı dönen bir patern’dir. Hata alınan ilk durumda akışın durdurulması olayına kısa devre (short-circuit) diyoruz. Bu sayede, hata sonrası işlemi durdurarak gereksiz yere hem sistemi yormamış oluyoruz hem de daha temiz ve okuması kolay kod yazmış oluyoruz.

Aşağıdaki görseli incelerseniz Validate, Update ve Email gönderme işlemleri sırayla yapılmaktadır. Eğer UpdateDb işleminde herhangi bir hata alınırsa SendEmail akışına girmeden kısa devre yaparak akış sonlandırılır. Bu sayede SendEmail operasyonları ile ayrıca ilgilenilmek zorunda kalınmaz.

Gelelim Arrow kütüphanesive fonksiyonlarından bahsetmeye. Arrow kütüphanesinde 4 adet modül bulunmaktadır. Bunlar Arrow Core, Arrow Fx, Optics ve Analysis modülleridir. Arrow kütüphanesi çok büyük ve tek bir yazıda anlatmak çok mümkün değil. Bu nedenle, ben bu yazımda Arrow Core modülü ve bu modül içerisinde en yaygın kullanılan fonksiyonları anlatmaya çalışacağım. Ayrıca, Arrow dokümanlarını incelemek isterseniz link bırakıyorum inceleyebilirsiniz.

Arrow Core

Kotlin’in standart kütüphanesinin tamamlayıcı bir kütüphanesidir. Arrow Core modülü yazdığımız kodlardaki basmakalıp ifadeleri azaltmayı hedeflemektedir . En yaygın kullanılan fonksiyonları Either, Validated, Effect, Option, fold gibi fonsiyonlardır. Ayrıca, Arrow Core, iterable genişletilebilir yöntemlerle hata yönetimi paternlerini de içermektedir. Diğer taraftan, call back durumlarını da ortadan kaldırarak daha kontrollü olan monad ifadelerini içeren direct syntax pattern’ini desteklemektedir.

Either

Arrow kütüphanesinde en çok kullanılan yöntemlerden biridir. Hata alınan ilk durumu yakalar ve geri döner. Üzerinde iki değer taşır. Bunlar sol ve sağ değerlerdir. Sol değer hata durumunu içerirken, sağ değer ise sonuç değerini içerir.

Exception kullanmak yerine aşağıdaki gibi Either kullanabiliriz ve bu sayede daha efektif bir kod yazmış oluruz. Aşağıdaki örneği incelerseniz, hata tiplerini sealed sınıf olan Error sınıfında tutuyoruz. Ayrıca when bloğu ile hangi hatanın Either’da sol tarafa atanacağını belirleyebiliyoruz. Diğer taraftan flatMap ve map ile fonksiyondan dönen değerleri map yapabiliyoruz. Ayrıca, flatMap ve map arasındaki temel fark, map 1–1 ilişkiyi desteklerken, flatMap 1-Many ilişkiyi desteklemektedir. Yani tek bir for döngüsü içerisinde yapabileceğimiz işlemler için map kullanıyoruz ama iç içe for döngüleri içerisinde işlem yapmamız gerekirse flatMap kullanıyoruz.

Bazı durumlarda exception durumunu daha belirgin hale getirmeye ihtiyacımız olabilir. Bu tür durumlarda Exception.catch kullanarak potansiyel hata alınabilecek bir yeri daha specifik bir hataya map edebiliriz.

Either.fx

İç içe gerçekleşen Either operasyonlarını daha az külfetli (cumbersome) zincir yapma şeklinde kod yazmamızı sağlıyor. Karmaşık zincir fonksiyon yapılarından uzaklaşarak, birbiri ardına zincir aksiyonlarını yazma şekline Monad Comprehension denmektedir. Aşağıdaki iki örneği de incelerseniz ikisi de aynı işi yapmaktadırlar. Fakat, Either.fx ile yazılan kodun daha anlaşılır ve temiz olduğu aşikardır. Either.fx içerisinde değişkenlerin val (header) şeklinde parantez kullanılmasının sebebi kısa devre olması durumunda değerin o blok üzerinden aşağıya düşmeden geri dönmesini sağlamaktır. Yani hata alma durumunda Either’ın sol tarafta bulunan değere atama yapılarak o blok üzerinden geri dönülür.

Option

Kotlin yapısı gereği null güvenlik mekanizmasına bağlı syntax ? ile null değeri sonucu oluşan hataları çözmeye çalışmaktadır. İşte Option, bu tür NullPointerException hataları ile başa çıkabilmek için oluşturulmuş bir fonksiyondur. Aşağıdaki örneği incelerseniz Option<String> değeri Some ile geçerli değer alabileceği gibi, None ile boş değer de alabilmektedir. Option’ a bağlı getOrElse methodu ise None değer gelmesi durumunda farklı bir değer atama yapmamızı sağlıyor. Bu sayede null durumlarını daha güvenli bir şekilde çözebiliyoruz. Bu konuda daha detaylı bilgi için link bırakıyorum.

fold

Either veya Effect gibi fonksiyonlardan sonra kullanılmaktadır. Fonksiyona bir devam oluşturarak gelen değeri override etmemizi sağlamaktadır. Aşağıdaki kodu incelerseniz biggerThanTen fonksiyonu içerisinde Either left veya right işlemlerinden bir tanesini geriye dönmektedir. Burada fold, Either’ın dönmüş olduğu değerleri alarak bu değerleri istenen değere override etmektedir. Aşağıdaki gibi hata alınması durumunda Either left’e atanan değerin sonucuna fold “Error occured” yazısını ekleyerek sonucu dönmektedir.

Son

Bu yazımda Arrow kütüphanesi ve bu kütüphanenin Kotlin’de nasıl uygulandığını anlatmaya çalıştım. Arrow kütüphanesini kullanmamızın functional programming’de belirli standartlarda kod yazmamızı sağladığından bahsettik. Ayrıca, Arrow kütüphanesinin, Monad Comprehension ve Railway patern’ini etkili bir şekilde kullanmamızı sağladığını gördük. Zaman ayırdığınız ve yazımı okuduğunuz için teşekkür ederim. Bir sonraki yazımda görüşmek üzere…👋

--

--