8 puan yazan GN⁺ 2025-08-15 | 2 yorum | WhatsApp'ta paylaş
  • OCaml’ın dil özellikleri ve ekosistemi mükemmeldir; hem kişisel hem de profesyonel projeler için uygundur
  • Statik tip sistemi, cebirsel veri tipleri, modül sistemi, nesne modeli, kullanıcı tanımlı effect’ler gibi çoklu paradigma ve gelişmiş özellikler kararlı biçimde entegre edilmiştir
  • OPAM paket yöneticisi, Dune derleme sistemi, LSP/Merlin editör desteği, Odoc dokümantasyon aracı gibi olgun bir araç zinciri vardır ve web, blokzincir, tooling gibi alanlarda çeşitli kütüphane ekosistemine sahiptir
  • Topluluğu erişilebilirlik, samimiyet ve uzmanlık özellikleri taşır; bu da öğrenme ve iş birliğini kolaylaştırır ve istikrarlı evrim sayesinde gelecek görünümü de olumludur

OCaml’ı ana dil olarak seçme nedenim

  • Yazar uzun süre boyunca çeşitli programlama dilleri kullandı ve bunların arasında OCaml’ı ana dili olarak seçti
  • OCaml’ın en büyük avantajları arasında güçlü statik tip sistemi ve C ya da diğer fonksiyonel dillere kıyasla üstün fonksiyonel programlama desteği sayılıyor
  • Söz konusu tip sistemi sayesinde birçok hata önleme ve kod optimizasyonu deneyimi yaşandı
  • Gerçekten de çeşitli geliştirme projelerinde OCaml kullanarak üretkenlik ve kararlılık açısından büyük iyileşmeler elde edildi

OCaml’ın avantajları ve pratikte kullanımı

  • Kodun büyük bölümü hızlı yazılabilir; fonksiyon bileşimi ve immutable veri kullanımı güvenliği artırır
  • Son dönemde OCaml’ın ekosistemi ve araçları (IDE, build sistemi vb.) da sürekli gelişmektedir
  • Çeşitli kütüphaneler ve harici paketler sayesinde iş ortamında verimli geliştirme mümkün hâle gelir
  • Python ve Java ile karşılaştırıldığında OCaml daha az bilinir; ancak üretkenlik, güvenlik ve esneklik açısından çok güçlü bir seçenektir

Dilsel özellikler

  • Araştırma kökeni ile endüstriyel uygulamanın birleşmesi, ifade gücü ve güvenlik odaklı özelliklerin gelişmesini sağlamıştır
    • kullanıcı tanımlı effect’ler, affine session gibi modern özellikler
  • Statik tip denetimi, bir güvenlik ağı ve tasarım aracı olarak işlev görür; zayıf tip deneyimlerinden kaynaklanan yanlış algıları ortadan kaldırır
  • Çoklu paradigma: fonksiyonel, imperative, modüler, nesne yönelimli, multicore desteği
  • ML ailesi sözdizimi kısa ve tutarlıdır; ReasonML gibi alternatif sözdizimleri de vardır
  • Cebirsel veri tipleri (çarpım, toplam, üstel tipler), pattern matching ve polymorphism ile veri/alan modellemesinde güçlüdür
  • Modül sistemi arayüz/uygulama ayrımı, soyutlama, yeniden kullanım ve gelişmiş polymorphism’e kadar destek sunar
  • Bağımlılık tersine çevirme: modüller/effect’ler üzerinden esnek enjeksiyon yaklaşımı sağlar
Reklam

Ekosistem ve tooling

  • Derleme hedefleri: native, bytecode, JavaScript(Js_of_ocaml, Melange), WebAssembly
  • MirageOS aracılığıyla çoklu bağlam kütüphaneleri yazmaya yönelik disiplin
  • OCaml Platform:
    • OPAM: sürüm yönetimi, switch’ler, paket indeksi, CI desteği
    • Dune: hızlı derleme, S-expression yapılandırması, dune-release ile dağıtımı sadeleştirme
    • LSP/Merlin: VSCode, Emacs vb. üzerinde kod tamamlama, gezinme, biçimlendirme
    • Odoc: çapraz referanslar, manuel sayfaları, doctest vb. desteği
  • Zengin kütüphaneler: web (Dream, Ocsigen), blokzincir ve kriptografi (HACL*), test (alcotest, qcheck vb.)
  • Standart kütüphane küçük olsa da Batteries, Base/Core, Containers gibi alternatifler vardır

Yeni meydan okumalar ve topluluk

  • OCaml topluluğu küçük olsa da istikrarlı biçimde büyümekte ve kullanıcı dostu bir eğilim göstermektedir
  • Yeni bir dil ya da paradigma konusunda meydan okuma arayan geliştiriciler için OCaml, derinlemesine öğrenmeye değer bir seçenektir
  • Pek çok kullanıcı, OCaml deneyimi sayesinde yeni bakış açıları ve problem çözme becerilerinin arttığını belirtmektedir

Sonuç

  • OCaml, belirli alanlarla (ör. finans, derleyiciler, sistem geliştirme) sınırlı kalmayıp genel amaçlı olarak kullanılabilen güçlü bir programlama dilidir
  • Pratikte elde edilen verimlilik, bakım kolaylığı ve sorunları önleme yeteneği, gerçek iş ortamında onun değerini kanıtlar
  • En yeni diller ya da trendlerle kıyaslandığında biraz daha az biliniyor olsa da, güvenilirlik ve güvenliğe önem veriliyorsa kesinlikle değerlendirmeye değer bir seçenektir

2 yorum

 
ng0301 2025-08-17

Bir ara yüksek lisansta OCaml ile uğraşmıştım ama ekosistemi gerçekten çok zayıf, referans da pek yok ve özellikle soru soracak kimse bulunmuyor. Kişisel ölçütlerime göre ülkemizde programlama dilleri camiası dışında kullanan neredeyse yok denecek kadar azdır. COBOL gibi şeyleri duymuş olsalar da OCaml'ı muhtemelen duymamışlardır..

 
GN⁺ 2025-08-15
Hacker News görüşleri
  • Google'da Rust'ın Android ekibine tanıtılması deneyimiyle ilgili bir sunum izlemiştim. Orada iki şey özellikle dikkatimi çekmişti: çeşitli projeler Python'dan Rust'a taşınmıştı, yani performans muhtemelen o kadar da büyük bir mesele değildi; ayrıca Rust kullanıcılarının en sevdiği özellikler pattern matching ve ADT'ler (Algebraic Data Types) gibi temel şeylerdi. Bu yüzden Rust'ın gerçekten büyük katkısının lifetime gibi kendine özgü özelliklerinden çok, 1990'lardaki ML dillerinin zaten sunduğu unsurlar olduğunu hissettim. Eğer OCaml 2010 civarında multicore gibi pürüzleri çözmüş olsaydı, bence Rust kadar popüler olabilirdi. Ne yazık ki OCaml akademi ile endüstri arasındaki boşlukta kaldı. Bir ek not olarak, 31 bit tamsayılar bit işlemlerinde pratikte can sıkıcı ve estetik açıdan da çift noktalı virgülü hiç sevmedim

    • Bence OCaml o dönemde zaten oldukça iyi durumdaydı. 2010'da profesyonel olarak Python'dan çok daha keyifli kullanıyordum. JaneStreet'in başardıklarına bakmak yeterli. OCaml'in yaygın biçimde benimsenmemesinin en büyük nedeni, ABD'de yapılmamış ya da oradan yönlendirilmemiş olması diye düşünüyorum. Bir dilin popülerliğinin teknik üstünlükten kaynaklandığına inanmak isteriz ama sonuçta mesele moda. Rust'ın kitlesel başarı kazanmasının nedeni de büyük ölçüde yoğun tanıtım ve aktif topluluk çalışmasıydı. Hatta buna adanmış çalışanları bile vardı

    • Google, gerçek servis kodunda kullanılabilecek resmi dil listesini olabildiğince kısa tutmaya çalışıyor. Rust'ın muhtemelen C++'ın yerini alabilecek ya da onu tamamlayabilecek bir dil olduğu için seçildiğini düşünüyorum. OCaml'in böyle bir konuma gelmesi zordu (Go'nun yerini alabilirdi ama olasılık düşüktü). Dolayısıyla Rust'ın seçilmesinin en büyük nedeni, ADT sunan resmi diller arasında tek seçenek olmasıydı; build hızını önemsememeleri değildi. OCaml'in Rust'ın yerini alamaması da gayet doğal. GC'li diller olarak zaten Go, Haskell vb. vardı ve 2010 civarında bare metal hedefleyebilecek kadar ifade gücü yüksek tek dil C++'tı (o da C++11 ve C++17 öncesinde daha kötüydü)

    • Kesinlikle katılıyorum. OCaml birkaç ufak sorunu çözebilseydi gerçekten önemli bir oyuncu olabilirdi. Build hızı bugün bile Rust'tan çok daha hızlı. Ama OPAM (paket yöneticisi) sık sık bug çıkarıyor ve kafa karıştırıcılığıyla ünlü. Windows desteği aşırı derecede kötü. Geçmişte Perl'ün Windows desteğinden bile daha kötü. Resmî dokümantasyon o kadar kısa ki neredeyse işe yaramaz. Söz dizimini anlamak da zor ve küçücük bir yazım hatası yüzünden dosyanın yarısının syntax error verdiği mesajlar görmek çok yaygın. Rust'ın mevcut C tarzı sözdizimi çok daha kolay. Özetle, OCaml'in avantajı hızlı build almak ama sadece bu da onu özellikle seçmek için yeterli değil

    • Bu yüzden ML tarzında programlama yapmak istediğimde Rust'tan önce Kotlin, Scala ve F#'a bakıyorum. Hatta bugünlerde Java ve C# bile yeterince çok ML özelliği benimsediği için bana çok yabancı gelmiyor. Caml Light ve Objective Caml günlerinden beri ML tip sistemine alışığım ama bugün insanların Rust'a bu kadar heyecan duymasını görünce sanki Rust ML tip sistemini yeni getirmiş gibi bir yanılgı oluşuyor

    • OCaml'in daha iyi hazırlanmış olmasını dilerdim görüşüne karşılık, aslında bence asıl büyük avantaj dil seçeneğinin bol olması. Sadece Birleşik Krallık'ta bile (nüfus az olsa da) çok farklı diller birlikte yaşıyor. Mesela Avrupa'nın ölü dillerinden Cornish bile son dönemde yerel halk tarafından canlandırıldı ve çobanlar arasında Kubrik diye sayma amaçlı bir dil de hâlâ var. Ben de gelecek nesiller için aile ağacımı tutmak adına OCAML tabanlı Geneweb adlı programı kullanmaya başladım (TMG adlı Windows uygulamasından geçtim). İçinde 140 bin kişi var. Geneweb'in OCAML ile yazılmış olması dile ilgimi artırdı. Programlama dilleri size zorsa, bir de soy ağacı/genealogy ile uğraşmayı deneyin derim. Yakında GEDCOM yüzünden başınız ağrımaya başlar

  • OCaml sevdiğim dillerden biri. En büyük işim, Writer's Festival organizasyonu için bir CRUD uygulamasını OCaml (ReasonML tabanlı JSX), Dream, HTMX ve DataTables ile %100 yapmak oldu. Modüller üzerinden frontend şablonlarını yeniden kullandım ve veri modelinde bir değişiklik olduğunda derleyicinin tam olarak nerede bozulduğunu göstermesinden çok memnundum. Excel verisini düzgün bir veritabanına taşımaktan .odt formatındaki takvim şablonlarını ya da sunucu diskine uğramadan doğrudan zip dosyaları üretmeye kadar, OCaml ekosisteminde şaşırtıcı derecede çok şey yapılabildi. Ama DB sorgularını tamamen string olarak yazmak ve tip dönüşümlerini elle yapmak zorunda kalmak inanılmaz yorucuydu (compile time type check yoktu). Kimlik doğrulama sistemini de kendim yazmak zorunda kaldım; yani asıl ürün geliştirme yerine çekirdek olmayan işlere gereğinden fazla zaman harcadım. Birçok dili dolaştıktan sonra vardığım sonuç şu: kusursuz dil yok. Her dilin kendine özgü eksileri var. Şu anda kendim için bir uygulamayı Rails ile yapıyorum; ihtiyacım olanların çoğu varsayılan olarak geliyor ve bu yüzden dilden çok gerçek layout tasarımı ya da fiilî deployment gibi asıl işlere odaklanabildiğim için daha memnunum

    • Güçlü tipli fonksiyonel dillerde DB sonucunu işlemenin idiomatik yolu nedir merak ediyorum
  • DarkLang önce OCaml ile geliştirildi, sonra F#'a geçti. Bunun başlıca nedeni kütüphane ekosistemi ve concurrency idi (ilgili yazı). .NET'e alışık olduğum için biraz önyargılı olabilirim ama sıkıcı kısımlar için bile pek çok hazır seçenek var ve bu da esas problemlere odaklanmayı kolaylaştırıyor. F#'ı profesyonel olarak epey kullandım, popüler bir UI kütüphanesini de sürdürüyorum, ama dil ekosistemi küçük olduğu için .NET dünyasında bile çözüm her zaman elinizin altında olmuyor. Bu yüzden ana akım dışı bir dil seçmenin (ör. C# yerine F#) bir maliyeti olduğunu akılda tutmak gerek. OCaml için de aynı durum geçerli; dil güçlü ama ana akım dışında olduğu için çeşitli sürtünmeler yaratıyor. Bazı şirketler bunu prod ortamında kullanıyor ama bunlar kendi özel ihtiyaçlarına göre şekillenmiş örnekler

  • Birkaç yıl boyunca OCaml'i sevmeye çalıştım ama en rahatsız edici yanı, "rastgele bir nesneyi print edememek" oldu. ppx ile otomatik to_string türetilebiliyor ama ayarı uğraştırıcı ve Rust'a göre kullanım deneyimi daha zayıf. Set, Map gibi tipleri yazdırmak için de ek iş gerekiyor (örnek tartışma). golang'de "%v" formatlamasıyla neredeyse her şeyi kolayca yazdırabiliyorsun ama OCaml bu açıdan daha fazla el işi istiyor

    • Go'nun %v formatlaması da kusursuz değil; pointer'ları daha derin dolaşmak için ayrıca go-spew gibi bir kütüphane gerekiyor. Python'ın __repr__ yaklaşımı, şimdiye kadar gördüklerim arasında en rahatı
  • OCaml'i doğrudan kullanmadım ama F# ile çalışmak çok keyifliydi. Bugünkü LLM çağında fonksiyonel dillere yeniden bakmak iyi olabilir diye düşünüyorum. OCaml ve Haskell gibi fonksiyonel paradigmada bilgiyi daha küçük bir metne verimli biçimde sıkıştırmak mümkün olduğundan, belki LLM'in context window'una da daha fazla anlam sığdırılabilir. Java, C# ve Ruby'ye kıyasla daha karmaşık değişiklikler bile tek seferde uygulanabilir; denemeye değer

    • Ben de başta öyle sanmıştım ama büyük bir Haskell kod tabanında çalışınca fikrim değişti. Eğitim veri setlerinde FP az olduğu için mi bilmiyorum ama daha özlü diller LLM'lere pek uymuyor gibi. Kod verbose olduğunda, LLM yanlış token tahmin ettikten sonra kendini düzeltmek için daha çok fırsat buluyor ve sanki daha doğru kod üretiyor

    • Kendi küçük deneyimde C++ ve Haskell ile basit bir CLI oyunu yaptım; satır sayısı Haskell'de daha azdı ama kelime sayısı neredeyse aynıydı, yani sadece kod daha "geniş" görünüyordu. Java ya da daha açık yazılan dillerle karşılaştırmadım ama bence hangi stilin uygun olduğu programın doğasına bağlı. Bazı şeylerde imperatif stil, bazılarında ise fonksiyonel stil daha uygun olabilir

    • LLM'lerin kod üretme becerisi biraz daha gelişirse, çok güçlü tip sistemleri ve effect sistemleriyle kodun davranış alanını sınırlayabilmek harika olurdu. Mesela dependent types varsa, "bu fonksiyon mutlaka sıralanmış bir liste döndürür" ya da "bu fonksiyon mutlaka geçerli bir Sudoku çözümü döndürür" gibi koşullar compile time'da doğrulanabilir. Buna bir de effect sistemi eklenirse, "bu fonksiyon geçerli bir Sudoku çözümü döndürür ama ne ağa ne de dosya sistemine erişir" demek de mümkün olur. LLM'ler daha da gelişirse belki bunların benzerini Python'da da yapabilirler ama ilerleme yavaş kalırsa, güvenilir olmayan LLM'leri güvenilir deterministik sistemlerle çevreleyip kullanmak geleceğin yönü olabilir

    • Scala'da cats-effect (effect kütüphanesi) kullanırken LLM yardımıyla geliştirme hızım inanılmaz arttı. cats-effect kodu, basit kavramlarda bile gereksiz zorlayıcı hissettirebiliyor ama LLM'e sadece "cats-effect'te şunu nasıl yaparım?" diye sormak çoğu zaman %80 oranında hemen çözüm veriyor. Kalan %20 için biraz daha bağlam eklemek yetiyor. Bakım tarafında hâlâ deneme aşamasındayım ama effect tabanlı fonksiyonel programlamanın yarattığı hayal kırıklığı ciddi biçimde azaldı. Bir dahaki sefere Claude Code'un bunu ne kadar iyi yaptığını denemek istiyorum

    • Haskell'in LLM ile kod üretiminde iki büyük avantajı var. Birincisi, ifade gücü yüksek tip sistemi pek çok hatayı yakalıyor; ortaya çıkan derleme hatalarını tekrar LLM'e geri bildirim olarak verebiliyorsun. İkincisi, property-based testler (QuickCheck vb.) sayesinde kodu verimli ve doğru biçimde iyileştirmek kolay. LLM testleri kendi başına çok iyi yazamıyor ama siz eklediğinizde üretilen koddaki bug'ları hızlıca buluyor

  • Bu yazıyı görünce "Neden F# yerine OCaml kullanayım ki?" sorusuna noktayı koydum. Neredeyse her OCaml başlığında birileri çıkıp "F# kullansan araç sorunları çözülmez mi?" diyor. Ben de OCaml'i merak ediyordum ve "Go with types" lakabını gördüğüm için ilgimi çekmişti ama OCaml'in kendisi henüz bana tamamen cazip gelmiyor. Erlang, Ruby, Rust ve Zig gibi diğer dil topluluklarındaki tutkuya benzemeyen bir havası var

    • Ben tam tersine F# araç ekosisteminden kaçıp OCaml'e geçmiş biriyim. F# kullandığım dönemde derleyici yavaştı; ekosistem C#'a odaklıydı; MSBuild zayıftı ve dokümantasyonu da kötüydü; Ionide sürekli çöküyordu; Fantomas da güvenilir değildi. Tabii OCaml de F#'ın performans odaklı özelliklerinin hepsinin yerini tutmuyor (ör. value type'lar gibi CLR'ın desteklediği şeyler). Bu yüzden hâlâ basit bir ML ailesi dili bulabilmiş değilim. Belki ileride OxCaml vb. bunu çözer diye umut ediyorum

    • Son zamanlarda OCaml'i çok kullanmıyorum ama dilin özü hâlâ en sevdiğim çekirdeklerden biri. Kod yazma stilim devasa tek bir fonksiyona kayma eğiliminde ama OCaml bunu doğal biçimde engelliyor. Yan projelerde Rust kullanıyorum ama dürüst olmak gerekirse OCaml daha rahat. Bu yüzden F#'ı da mutlaka bir ara denemek istiyorum

  • Terminolojiyle ilgili bir sorum var: yazıda fonksiyon tipleri için "üstel tipler (exponential types)" deniyor ama higher-order function tiplerine neden böyle dendiğini tam anlamadım

    • Zaten iyi bir açıklama verilmiş ama daha derindeki neden şu: fonksiyon tipleri cebirsel olarak üs kurallarına uyuyor. Örneğin A → (B → C), currying sayesinde (A × B) → C ile izomorfiktir. Bu da (cᵇ)ᵃ = cᵇ˙ᵃ kuralına benzer. Ayrıca (A + B) → C, (A → C) × (B → C) ile izomorfiktir; bu da cᵃ⁺ᵇ = cᵃ·cᵇ kuralına karşılık gelir

    • Birinci dereceden fonksiyon tipleri de zaten üstel. Mesela bir sum type, case sayısı kadar değere sahiptir. (A of bool | B of bool2+2=4 olası değer). Product type'lar ve exponential type'lar da aynı şekilde. bool -> bool dersen 2^2 = 4 olası değer vardır (yan etkileri saymazsan)

    • Genelde ADT (Algebraic Data Type) konuşurken sadece sum ve product ele alınıyor. Fonksiyonlar veri olmadığı için çok anılmıyor. Ama a -> b tipi b^a kadar olasılığa sahip olduğundan aynı şekilde ele alınabilir

    • Benim de aynı sorum vardı ama matematikte toplama (sum), çarpma (product) sonrası üs (exponent) geldiği için mecazi olarak böyle deniyor sanıyordum

    • Yanıtların hepsi doğru ama aslında category theory'de fonksiyon tipine "exponential product" deniyor. Bu ad da A'dan B'ye fonksiyon sayısının, B'nin kardinalitesi üzeri A'nın kardinalitesi olarak hesaplanmasından geliyor

  • Sum types: örneğin Kotlin, Java ve C# belirli case'leri kendi tipleri gibi ele almak için sealing (kalıtımı kapatma) kullanabiliyor
    sum type bildirimleri uzun ve anlaşılması zor deniyor
    sum type genelde bir kez tanımlanır, sonra birçok kez kullanılır. Eğer case'leri kullanım sırasında daha temiz yazabiliyorsak, tanım sırasında biraz uzun olması bence tamamen kabul edilebilir

    • sum type'ın case'leri, type constructor üzerinden kurulan değerler (expression) olduğundan elbette tip taşırlar. Örneğin,

      datatype shape =
         Circle of real
        | Rectangle of real * real
        | Point
      

      her bir case'in bir tipi vardır. Pattern matching sayesinde type constructor parametrelerini zaten doğrudan unpack ediyorsun. Case'leri ayrı tiplere bölmek, sum type'ın sunduğu exhaustiveness avantajını kaybettirir ve hatta yanlış program durumlarını ifade etmeyi mümkün kılar. Sum type'lar bir kez tanımlanır, birçok kez kullanılır ve çoğu zaman disposable yapıdadır. Kodun okunabilirliği de önemlidir; uzunluğun maliyeti bazen küçümseniyor. Bu arada C#/Java gerçek anlamda sum type desteklemiyor. Aşağıdaki örnekte C#'ın OOP yaklaşımı yüzünden gereksiz yere karmaşıklaştığını görebilirsin

      public abstract record Shape;
      public sealed record Circle(double Radius) : Shape;
      ...
      double Area(Shape shape) => shape switch {...};
      

      ML'de ise çok daha kısa

      datatype shape = Circle of real | Rectangle of ... | Point
      val result = case shape of ...
      

      İki yaklaşım neredeyse aynı ama C#'taki OOP unsurları burada ayak bağı oluyor

    • OCaml'de GADT, polymorphic variant vb. ile bunları ayrı tipler gibi de kullanabilirsin. Ama genel olarak sum type'ı bölmek hem genellemeyi zorlaştırır hem de anlamayı güçleştirir. Beraberinde type equality ve variance sorunları da gelir

    • Sum type ile sealed type tartışmasının neden bu kadar büyüdüğünü anlamıyorum. Fonksiyonel dilleri daha çok sevsem de, type level ayrım yapabildiğin sürece sealed type'larla da sum type'ların hepsi modellenebilir ve subtyping sayesinde tanım ve kullanım bazı yönlerden daha kolay olabilir. Sistemlerin paradigması çok farklı ama matematiksel olarak neredeyse denktirler; OOP ve FP tarafında yapılabilecek type oyunlarının çoğu da dilin izin verdiği ölçüde gerçekleştirilebilir

    • Java/Kotlin'deki sum type bildiriminin uzunluğunun buna değdiğine katılmıyorum. Bana daha çok JVM dillerinin tipik boilerplate yükü gibi geliyor

  • ReasonML sözdizimini bu kadar iyi bilen birinin artılarını ve eksilerini karşılaştırmasını isterdim. (Yazıda kısaca değinilmişti)

    • Benim en çok özlediğim şey let binding'lerdi (resmî doküman). ReasonML'de monad'lar için >>= gibi operatörleri doğrudan özelleştirip rahat kullanabiliyordun. rescript'te (ReasonML'in fork'u) bu hâlâ yok. Onun yerine async/await sözdizimi iyi destekleniyor; asenkron kodda işe yarıyor. Melange (yazıda kısaca geçiyor) ise Reason sözdiziminde let binding desteği veriyor. Bu yüzden React tabanlı frontend'de Melange'in Reason ML'i çok avantajlı. Let binding sayesinde (JSX ile birlikte) monadik tarzda asenkron kod da temiz yazılabiliyor. OCaml sözdiziminde bunu PPX ile dolanmak mümkün ama editörde syntax highlighting iyi çalışmıyor. Backend açısından bakınca, ben Python tarzını sevdiğim için süslü parantezler hâlâ gözüme batıyor ve fonksiyon çağrısı/tanımında parantezsiz yazmayı tercih ediyorum. Ama yeni bir OCaml kullanıcısı olarak, değişken olmayan argümanlar geçerken parantez kullanımı hâlâ kafamı karıştırıyor. Umarım bu deneyim faydalı olur

    • ReasonML'i pek kullanmadım, o yüzden avantajlarını hissetmedim. Tabii 4 yıl içinde iki kez ölmüş olması dışında...

    • Reason sözdiziminin daha yaygın olmasını isterdim ama OCaml topluluğuyla iletişim kurmak için standart sözdizimini öğrenmek daha mantıklı. Kodların ve dokümanların çoğu standart sözdiziminde, yani eninde sonunda bilmek gerekiyor

    • Benim yaşadığım ReasonML deneyiminde en can sıkıcı şey LSP'nin düzgün çalışmamasıydı

  • dependency injection'ın effect system ile nasıl uygulandığını daha ayrıntılı anlatmalarını isterdim. Pattern matching ile test/prod değerlerini bağlama fikri ilginç görünüyor ama yazıdan tam oturtamadım. Ayrıca module system'in kendi tip sistemine sahip olduğunu ilk kez duydum, o da çok ilginç geldi

    • Ben bir Haskeller'ım!

      Örnekte pattern matching ile test/prod değer bağlama kısmının oturmadığı yorumuna karşılık... Yazının sözünü ettiği şey free monad + interpreter pattern'i: iş mantığında aksiyonları doğrudan çalıştırmak yerine, işlemleri isimlendirilmiş düğümler olarak bir AST'ye biriktiriyorsun. AST oluşunca da ProdAstVisitor, TestAstVisitor gibi yapılarla gerçek çalışma ve testi ayırabiliyorsun. Somut olarak, AST'nin her düğümünde Test.ReadFile / WriteFile seçmekten bahsediliyor; Test ve Prod doğrudan birbirine karışmıyor. Haskell topluluğu ise son dönemde, daha az ceremony gerektirdiği ve aynı etkiyi sağladığı için free monad + interpreter yaklaşımından biraz uzaklaşıp tagless final yaklaşımına kaydı. effect system ile DI'ı daha fazla görmek istediğini söyleyen yoruma karşılık... Ben DI'ı effect'lerle yapıyorum. Memnun olduğum yapı şu: En altta readTextFile, writeTextFile gibi işlevlere bölünmüş capability arayüzleri var. Bu sınıfların domain bilgisi hiç olmamalı. Onların üstünde, bu capability'leri iş bilgisiyle birleştirip fetchStoredCommands gibi business function'lar yazıyorsun. En üstte de CliApp diye bir tip var ve burada capability arayüzlerinin gerçek implementasyonlarını bağlıyorsun. Mesela Logger için ayrı bir mock implementasyon bağlarsan, prod/test ortam ayrımını typeclass'larla kurmuş oluyorsun. Kritik nokta şu: tüm fonksiyonun effect türü (IO olup olmaması gibi) tip sisteminde açıkça yer alıyor. Gerçek prod implementasyonu IO kullanabilir ama test implementasyonunda IO yasak olur. Eğer yeni bir capability (Caching gibi) eklersin de test implementasyonunu unutursan, bu compile time hatası olarak yakalanır; bu da güçlü bir güvence sağlar. OCaml'de de buna benzer bir yaklaşımın mümkün olup olmadığını merak ediyorum. Çünkü yazıda effect yayılımının henüz tip sistemi tarafından izlenmediği söyleniyordu