2 puan yazan GN⁺ 2023-08-26 | 1 yorum | WhatsApp'ta paylaş
  • Yaklaşık 2009’dan 2019’a kadar Haskell’i ana dili olarak kullanan bir programcı, artık kişisel projelerde ve iş ararken Haskell’i varsayılan seçenek olarak görmüyor
  • Haskell’in çekiciliği monadlar ya da DSL’lerin kendisinden çok, cebirsel kod akıl yürütmesi ile güçlü tip sisteminin sağladığı güvenli refaktör ve değişmezlerin ifade edilebilmesiydi
  • Uzaklaşmasının nedeni, gelişmiş tip özelliklerini tercih eden kültür, pürüzsüz olmayan araçlar ve GHC ile standart kütüphanedeki sürekli uyumsuz değişikliklerin birikmesi
  • Buna rağmen yüksek mertebeden fonksiyonlar, do notasyonu, lens’ler, bildirime dayalı kütüphaneler ve gelişmiş tip soyutlamaları, diğer dillerin kolayca ikame edemediği güçlü yanlar olmaya devam ediyor
  • Haskell, daha iyi bir programcı olmak için öğrenmeye fazlasıyla değer; ancak bir organizasyonun varsayılan dili yapmak için araç kalitesi ve dil kararlılığı maliyetini göze almak gerekiyor

Haskell’i varsayılan dil olarak kullandığı dönem ve bugünkü konumu

  • Yaklaşık 10 yıl boyunca Haskell, yeni projeler için varsayılan dildi
    • 2009 civarında Haskell ile tanıştıktan sonra, 2019 civarında ağırlıklı olarak Ruby ve C++ kullanılan bir işe geçene kadar kendisini bir Haskell programcısı olarak gördü
  • Komut satırı araçları, web servisleri, grafik uygulamaları, küçük betikler gibi farklı amaçlarla Haskell kullandı
  • Bugün Haskell’i tamamen reddetmiyor; ancak kişisel projelerde de varsayılan dili değil ve eskisi gibi özellikle “Haskell işi” aramıyor
  • Bu değerlendirme, Haskell’in kötü olduğu sonucundan çok, kişisel olarak Haskell’den neden uzaklaştığının açıklaması

Haskell’e çekilmesinin nedenleri

  • Kodu cebirsel olarak ele alabilme özelliği

    • Haskell’in en büyük çekiciliği, kod üzerinde sembolik ve cebirsel akıl yürütme yapılabilmesiydi
    • Örneğin double n = n + n adlı bir fonksiyon varsa, double x ifadesini x + x ile değiştirmek Haskell’de her zaman doğrudur
    • Birçok emir kipli dilde double(i++) ile (i++) + (i++) farklı çalışabilir
      • İlki i’yi bir kez artırır
      • İkincisi i’yi iki kez artırır
    • Bu özellik sayesinde küçük mekanik dönüşümler biriktirilerek büyük refaktörler daha güvenli yapılabilir
    • Ruby kod tabanında büyük refaktörler oldukça tedirgin edici olabilirken, Haskell kod tabanında çok daha kolay olabilir
  • Sıkı ama gereksiz yere gürültülü olmayan tip sistemi

    • Haskell’in tip sistemi sıkıdır; ama tip çıkarımı sayesinde Java’daki kadar aşırı tip yazımı gerektirmez
    • Typeclass’lar da tipleri düşünmek gereken durumlarda uğraşı azaltır
    • İyi Haskell kodu “kolay kırılan(brittle)” bir özellik taşır
      • Hatalı soyutlama sessizce eğilip bükülerek yanlış programlara izin vermez
      • Bir sorun varsa derleme başarısız olur
    • NonEmpty tipi, en az bir öğe içeren listeyi temsil eder
      • map gibi uzunluğu koruyan işlemler NonEmpty döndürür
      • append gibi uzunluğu artıran işlemler de NonEmpty döndürür
      • filter gibi sonucu boş olabilecek işlemler normal liste döndürür
    • Dosya yolu listesinin NonEmpty olması gereken bir fonksiyona komut satırı argümanları doğrudan verilemez; önce boş olmadıkları doğrulanmalıdır
    • Sonradan uzantı filtreleme adımı eklenirse sonuç boş olabileceğinden tekrar kontrol gerekir ve yanlışlıkla boş liste gönderilen yol derleyici tarafından engellenir
  • Değişmezleri tiplerle koruma yaklaşımı

    • Uzun süre Haskell kullanınca, programın değişmezlerini tiplerle ifade edip bunları derleyiciye doğrulatmaya alışılıyor
    • Bu, yalnızca karmaşık tip seviyesi hesaplamaları anlamına gelmez
    • SQL kaçışının yapılıp yapılmadığı RawString ve SanitizedString gibi sarmalayıcı tiplerle ayrılabilir
      • Web API’si RawString verse bile, veritabanı katmanı yalnızca SanitizedString kabul edecek şekilde kurulabilir
    • Çok sayıda Maybe alanı içeren yüzeysel temsil, gerekli bilgilerin varlığının garanti edildiği iç temsile dönüştürülebilir
    • Bağımsız test yapılabilecek kadar jenerik tasarlama yaklaşımı da mümkündür
  • DSL’lerin ve yüksek mertebeden fonksiyonların doğal olduğu bir dil

    • Haskell, makrolar olmadan da kısa ve öz alana özgü diller oluşturmayı kolaylaştırır
    • config-ini, INI yapılandırma dosyalarını ele alan bir kütüphane örneğidir
      • Emir kipli bir ayrıştırma arayüzü yerine bildirime dayalı bir arayüz kullanır
      • Yapılandırma tipinin belirli kısımlarını INI dosyası yapısının belirli kısımlarına eşler
      • Aynı arayüzle okuma, yazma ve diff-minimal update yapılabilir
    • Ruby DSL’leri dinamik metaprogramlama ve küresel monkeypatching’e dayanabilir; Haskell DSL’leri ise esnek sözdizimi ve monad aşırı yüklemesi gibi özelliklerle belirli dosya ya da kod bölgesiyle sınırlanmayı kolaylaştırır
    • Haskell, yüksek mertebeden fonksiyonlarla çalışmayı da doğal hale getirir
      • (+), iki sayısal argüman alıp toplayan bir fonksiyon olarak doğrudan kullanılabilir
      • pairwiseProduct = zipWith (*) gibi bir ifade ile iki listenin öğe bazlı çarpımı çok kısa yazılabilir
    • Haskell için, Perl’in dizgileri işlemeyi kolaylaştırdığı gibi fonksiyonlarla çalışmayı kolaylaştırdığı benzetmesi yerinde olur

Haskell’den uzaklaşmasına yol açan üç etken

  • Zorlayıcı stilleri tercih eden atmosfer

    • İlk etken tarz düzeyinde yeni teknoloji merakıydı
    • Haskell topluluğu sürekli yeni soyutlamalar deniyor ve inşa ediyor
      • Soyut cebir ya da kategori teorisinden alınan yaklaşımlar
      • Daha fazla hesabı tip seviyesine taşıyıp hatalı durumları sınırlamaya çalışan yaklaşımlar
    • Servant’ın tip seviyesi web API’si ya da comonad ile menü sistemi ifade eden örnek, problem alanını yeni yollarla ifade etme denemeleridir
    • Ancak günlük kodda bu tür deneysel yaklaşımlar, ilk bakışta sundukları avantajdan daha fazla sorun çıkarabiliyor
    • Derleyici projesindeki bir örnekte AST düğümleri, ifade tipini bir tip parametresi olarak taşıyordu
      • Tip hatası içeren bir sözdizim ağacı oluşturulursa derleyicinin kendisi derlenmiyordu
      • Başlangıçta birkaç hatayı yakaladı
      • Birçok optimizasyon geçişi tip disiplinine uymadığında, cast’ler ve GHC’yi ikna etmeye çalışma kodu karmaşıklaştırdı
      • Sonunda AST’den tip parametresi kaldırıldı
    • “fancy types” yaklaşımının denendiği projelerin yaklaşık dörtte üçünde bunun yeterince değer üretmediği sonucuna varıldı
    • Simple Haskell yaklaşımı, deneysel özelliklerden kaçınıp en az genişletmeyle kalındığında dilin avantajlarından en çok yararlanıldığı fikrine dayanır
    • Daha karmaşık tip özellikleri topluluk ve kütüphanelere geniş ölçüde yayılmış durumda
    • Karmaşık tip soyutlamaları değişiklik ve bakımı zorlaştırabiliyor; daha basit bir soyutlamayı yeniden en güncel tip seviyesi soyutlamayla değiştirme girişimlerinin kod boyutunu artırdığı, performansı düşürdüğü ve okunabilirliği azalttığı deneyimlenmiş
    • Yine de Trees that Grow, derleyici aşamalarına göre indekslenmiş veri yapılarıyla faydalı bulunan bir “fancy type-level feature” örneği olarak kalmış
  • Günlük işlerde parlamayan araçlar

    • İkinci etken garip araç ekosistemiydi
    • Haskell’de fiilen standart sayılabilecek çeşitli derleme sistemleri ve geliştirme araçları bulunuyor
    • Bu araçlar genel olarak gereken işi yapıyor; ama “sevilecek” seviyede değillerdi
    • ormolu gibi en az sürtünmeyle işini yapan araçlar da vardı; ancak bazı araçlar sürekli hatalar ve geçici çözümler gerektiriyordu
    • Haskell araçları 10 yılda gelişti; ancak 2019 itibarıyla Rust Cargo düzeyinde kullanılabilirlik ve kararlılığa yaklaşan bir araç yoktu
    • Sürekli yeni ve daha iyisini yapma çabası içindeki Not-Invented-Here eğilimi de sorundu
      • Paket metin formatını bile hpack ile yeniden ele alma eğilimi vardı
      • Bu tür girişimlerin yıllarca %95 tamamlanmış halde kalması sinir bozucuydu
    • Bu, Haskell araçlarının berbat olduğu anlamına gelmiyor; ancak “idare eder” düzeyi, yükselen beklentileri karşılamıyor
  • Süregelen uyumsuz değişiklikler

    • Üçüncü etken, Haskell dili ile GHC’nin yaşadığı sürekli değişimdi
    • GHC, fiilen mantıklı tek açık Haskell uygulaması olarak görülüyor
    • Haskell, geçmiş hataları ve tutarsızlıkları standart kütüphane ile dilin temel parçalarında bile kademeli olarak düzeltmeye çalışıyor
    • Bu değişiklikler dili daha temiz ve tutarlı yapı taşlarına götürebilir; ancak kullanıcı tarafında sürekli küçük sürtünmeler yaratır
    • 2015 tarihli Foldable-Traversable Prelude changes, buna örnek gösterilebilir
    • Eski Haskell projeleri, harici bağımlılıkları olmasa bile en yeni GHC ile derlenmeyebilir
      • superclass eklenmesi
      • import kaldırılması
      • belirsizleşen çok biçimlilik nedeniyle tip imzası eklenmesi
    • Düzeltmeler genelde küçüktür; ama sürekli birikir ve eskiden biraz farklılaşmış noktalar kullanıcının dikkatini ister
    • Buna karşılık Rust’ın epochs güncelleme yaklaşımı, kararlı özellikler için geriye dönük uyumluluk sözünü açıkça tanımlar ve kasıtlı breaking change’leri epoch arkasına saklar

Hâlâ özlenen Haskell avantajları

  • Haskell’in cebirsel kod yazımı ve refaktör yaklaşımı hâlâ güçlü bir yön
    • Rust da Haskell ile birçok avantajı paylaşır; ancak küçük mekanik refaktörlerin program anlamını koruduğundan emin olmak Haskell’deki kadar kolay değildir
  • Tip sistemi de diğer dillerde genelde bulunmayan yetenekler sunuyor
    • 2023’ün ana akım dilleri, 2009’a göre statik tip özellikleri açısından ciddi ilerleme kaydetti
    • Buna rağmen higher-kinded types üzerindeki soyutlamalar gibi özellikler Haskell’i farklılaştırıyor
  • Haskell kütüphane ekosistemi karma bir görünüm sergiliyor
    • Yarı bakımlı açık kaynak kütüphaneler
    • Her yazarın dünyayı kendi tarzında yeniden kurmaya çalıştığı küçük krallıklar
    • Gerekli ama birbirinden farklı dize benzeri tipler
  • Buna rağmen Haskell’de, diğer dillerde ancak yarım yamalak mümkün olan harika kütüphaneler ve soyutlamalar var
    • Lens’ler, yeterince kullanılmadan avantajı kolay anlaşılmayan güçlü bir soyutlamadır
    • Brick, bildirime dayalı bloklarla çok iyi bir terminal UI kütüphanesi sunar
    • diagrams ve music-suite de bildirime dayalı API’lerin iyi örnekleridir
  • do notasyonu da çok özlenen bir özellik
    • Asıl mesele do’nun kendisinden çok, yeni binding’ler eklense bile girinti seviyesinin sürekli artmamasını sağlayan gösterimdir
    • Ruby’de iç içe flat_map kullanımı, her yeni eksende girintiyi derinleştirir
    • Haskell’in do notasyonu aynı bileşimi düz bir biçimde ifade eder
  • do notasyonu, async/await tarzı yapısal eşzamanlılığı, eşzamanlı işlemleri ve olasılıksal programları aynı hafif sözdizimiyle gömmeyi mümkün kılar

Haskell öğrenilmeli mi, kullanılmalı mı?

  • “Bu dili öğrenmeli mi, kullanmalı mı?” sorusunun yanıtı hedefe göre değişir
  • Amaç daha iyi bir programcı olmaksa Haskell öğrenmeye fazlasıyla değer
    • Haskell ilginç ve güçlü bir dildir
    • Haskell öğrenme deneyiminin programlama becerisini geliştirdiği düşünülüyor
  • Amaç gerçek kullanım ise daha dikkatli olmak gerekir
    • Haskell’in avantajları gerçekten vardır
    • Ancak bunlar, birey ya da organizasyonun yukarıda anılan sürtünmelere ne kadar katlanabileceğiyle birlikte değerlendirilmelidir
    • Haskell’den yeterince fayda görerek küçük rahatsızlıkları küçük yaralar düzeyinde tutabilen kişi ve organizasyonlar da vardır
  • Net bir evet-hayır istenirse, yanıt “Haskell kullanmayın” tarafına daha yakındır
    • Bir mühendislik organizasyonu kurulacaksa Haskell’i varsayılan dil yapma yönünde karar verilmezdi
    • Çünkü iyi araçların değerini ve kötü araçların maliyetini biliyor
    • Bunun yerine kararlı dil, açık bir kod ekosistemi ve üstün araçları hemen sunabilen diller tercih ediliyor
  • Yine de Haskell, program güvenliği ve doğruluğu için mükemmel araçlar sunar
    • Belirli bağlamlarda kötü araçlara ve gereksiz type family’leri engelleyen linting’e katlanmak buna değebilir
  • Haskell artık kişisel olarak uygun bir dil değil; ama Haskell dünyada hiç var olmasaydı, dünyanın daha kötü bir yer olacağı sonucuna varılıyor

1 yorum

 
GN⁺ 2023-08-26
Hacker News yorumları
  • Haskell’i yaklaşık 10 yıl kullandıktan sonra yakın zamanda geçim kaynağı olarak kullanmayı bıraktım; yazarın ilk tespitine kesinlikle katılıyorum: Haskell topluluğu öğrenmeye çok güçlü biçimde önem veriyor.
    Meraklı insanlarla çalışırken her zaman öğretecek ve öğrenecek bir şeylerin olması güzel; ancak denenmiş fikirleri bırakma konusunda zayıf kalıyorlar. Bu yüzden profesyonel Haskell kod tabanlarında, sıkı yönetilmezse “yapılabilir ama kullanmamak daha iyi” türünden şeyler kolayca birikiyor.
    Yalnız araç zinciri konusunda farklı düşünüyorum. Haskell araçlarının pek iyi olmadığı doğru; ama Python, JS, Java, Rust ve Elm kullandıktan sonra çoğu aracın da pek iyi olmadığını gördüm, hatta Haskell araç zincirini özledim. cargo harika ama daha çok istisna gibi; Rust yaşlandıktan sonra da bu durumu koruyup koruyamayacağını merak ediyorum.

    • Birçok dil kullandım ama Haskell’in araçları en kötülere yakındı. language server rastgele hatalarla sık sık bozuluyor; Haskell sürüm yönetimini ghcup’a mı yoksa stack’e mi bırakmak gerektiği de her seferinde kafa karıştırıyor.
      Ara sıra üzerinde çalıştığım bir proje var; bir dahaki açışımda yine çalışmayacağından %100 eminim. Python’un bağımlılık ve sanal ortam yönetimi de benzer şekilde kötü, ama Poetry oldukça iyiydi; Ruby’de chruby/rbenv/rvm’den hangisini kullanırsanız kullanın benzer şekilde iyi çalışıyor ve Bundler da düzgün işliyor. Java’nın kusurları olsa da IDE deneyimi en üst düzeyde; refactoring Haskell’deki kadar güvenli olmasa da çok kolay yapılabiliyor.
    • Cargo, Ruby’nin Bundler’ı gibi eski fikirlerden evrilmiş bir şey; bu yüzden bu tür araçlar arasında soyu epey eskiye dayanıyor.
      Bundler genel olarak fena değil; katılmadığım tasarım tercihleri olsa da doğru yoldan giderseniz birçok şey yerine oturuyor. Dil araçları da yeterince az bozuk bir şekilde yapılabilir; cargo’yu doğrudan çok kullanmadım ama gerçekten sınıfının en iyisiyse bu durumunu koruması şaşırtıcı olmaz.
    • Java araçlarının “pek iyi değil” kategorisine girdiğine inanmak biraz zor. Java’nın kendisi hakkında birçok olumsuz şey söylenebilir, ama ücretsiz ve ticari araçları benzersiz düzeyde.
    • Haskell araçları yüzünden yeniden ciddi biçimde dalma isteğim kayboldu. Buna karşılık Purescript, her kurcaladığımda oldukça pürüzsüz bir deneyim verdi; özellikle JS araçlarına aşinaysanız daha da öyle.
    • Araç tartışmalarında .NET dilleri ya da Swift’in neden eksik olduğunu merak ediyorum. Bunun nedeni Visual Studio veya Xcode gibi IDE’lerin birinci sınıf araçlar olması olabilir; ya da açık kaynak dünyasının büyük teknoloji şirketlerine bağımlılıktan kaçınma eğilimi olabilir.
  • Araçlar açısından Haskell’de, bildiğim kadarıyla başka dillerin rekabet etmekte zorlanacağı bir şey var: Hoogle.
    Hoogle şaşırtıcı derecede harika. Haskell ile ne istediğinizi söylersiniz, o da Haskell ile neler yapabileceğinizi söyler. Rust’ta da benzer denemeler oldu ve Nim için Noogle yapmayı da denedim; ama “bir fonksiyona argüman geçmek” ile “bir fonksiyonu çağırmak” ayrımının net olduğu dillerde aynı şekilde çalışmıyor.
    Result, Box iç içe geçmiş Rust kodu gördüğüm her seferinde Hoogle kadar kullanışlı bir Roogle olsaydı diyorum. Bunun dışında Haskell araçlarının bir avantajı yok. Bunun önemli bir kısmı, topluluğun mevcut olanı iyileştirmek yerine “yenilikçi” bir şey yapma içgüdüsünden kaynaklanıyor gibi görünüyor.

    • Hoogle’ın inanılmaz kullanışlı olduğuna güçlü biçimde katılıyorum. Diğer araçlar konusunda ise haskell-language-server’ı her gün kullanıyorum ve üretkenliğim çok daha iyi hale geldi.
      Mükemmel değil ama 5 yıl öncesine kıyasla çok daha iyi.
    • Hoogle gerçekten müthiş. Ondan ilham alarak C++ için fonksiyonel programlama kütüphanesi FunctionalPlus’ta da benzer bir şey uyguladım: https://www.editgym.com/fplus-api-search/
      Daha fazla projenin bu yönde ilerlemesi iyi olurdu.
  • Bence en büyük sorun, GHC’nin standart kütüphane olan belirli bir base sürümüne bağlı olması.
    base değiştiğinde ve yeni GHC sürümü yalnızca o sürümü desteklediğinde, daha yeni GHC kullanmak için fiilen tüm bağımlılıkları değiştirmeniz gerekiyor. GHC 9.6 ile derlenen kodun neden base 4.18.0.0 kullanmak zorunda olduğunu hâlâ anlamıyorum. GHC ikilisinin, derleme hedefi kodun Data.List modülü sürümüyle neden ilgilenmesi gereksin ki?
    base’in dışa açtığı GHC’ye özel öğelerin belirli bir GHC sürümüne bağlı olmasını anlıyorum; ama geri kalanının da öyle olması gerekip gerekmediğini bilmiyorum. Yine de bunu düzeltmek için base’i birden çok pakete bölme çalışmasının sürdüğünü anlıyorum: https://gitlab.haskell.org/ghc/ghc-wiki-mirror/-/blob/master...

    • Alıntıladığınız kısımda bir ipucu var. Daha yeni GHC, eski base kodunu geçersiz diye reddedebilir.
    • Çünkü iç veri tipleri farklı olabilir. Farklı base uygulamalarına linklenmiş kütüphaneler Data.List instance’larını birbirine geçiriyorsa sorun çıkar.
      Örneğin Data.List’ten bir listeniz olduğunda, iki farklı kütüphane fonksiyonunun sonuçlarını o listeye ekleyebilir misiniz?
    • Belirttiğiniz gibi yeniden kurulabilir base herkesin istediği hedef. Mevcut durum büyük ölçüde tarihsel nedenlerden ve derleyicinin içine bağlı temel öğelerin temel olmayan öğelerle birleşmiş olmasından kaynaklanıyor; yeterli çabayla daha iyi hale gelebilir.
  • Haskell’a ilgimin giderek azalmasının üç büyük nedeni varsa, bunlar bakımı zorlaştıran anlaşılmaz kodu yücelten üslup açısından yenilik düşkünlüğü, gündelik işleri daha hantal hâle getiren tuhaf araçlar ve ara sıra olsa da sürekli dikkat gerektiren, düzenli olarak kırılmalara yol açan devamlı değişimdi.
    Yerinde bir tespit. 2010–2012’de Haskell’i epey öğrenmiştim; dilin kendisi harikaydı ama dokümantasyon ve araçlarla uğraşmak zordu. Topluluk Cabal’dan meşhur Cabal hell’e, oradan Stack’e geçti, sonra tekrar Cabal’a döndü; genel olarak işler iyileşti.
    Öte yandan diğer programlama dilleri de fonksiyonel programlama öğelerini benimsedi. Örneğin Java Streams, fonksiyonlar, lambda’lar, cebirsel veri tipleri, records ve pattern matching ekledi; sözdizimi Haskell kadar zarif olmasa da fonksiyonel programlamanın temel kavramları içinde var.

    • Hapisten kaçmaya yönelik umutsuz bir girişim içinde mahkûmlar, dar parmaklıkların arasından görünen ışıktan ilham alan grotesk ritüelleri benimseyerek kendi dillerini kirlettiler.
      Böylece kendilerine sonsuz bir acı çukuru yarattılar; ancak ışık huzmesi, pencerenin dışındaki ağaçta ışığın oluşturduğu renkleri görecek kadar alçalmadığı için buna zar zor katlanılabilir oldu. Dışarıdan gelenler, kendi yarattıkları karanlığa uyarlanmış lehçe ile ışığın içinde serpilebilecek ama orada boğulan lehçe arasında parçalanır ve hızla akıl sağlıklarını yitirirler.
    • Sayılan özelliklerin çoğundan daha fazla, verimli değişmez veri yapıları fonksiyonel programlama için önemlidir. Java bu konuda ne sunuyor?
    • Cabal’dan Stack’e geçilip sonra tekrar Cabal’a dönüldüğünü bilmiyordum. Haskell’den birkaç yıldır uzaktayım; son kullandığımda Stack en sorunsuz seçenek gibi görünüyordu ve Cabal’ın pek çok acısını çözmüş gibiydi.
      Topluluk yeniden Cabal’a döndüyse neyi kaçırdığımı merak ediyorum.
  • Bu nedenlerden dolayı F#’a geçtim ve pek geriye bakmadım. Bazen higher-kinded type’ları özlüyorum ama F#’ta da generics var; dürüst olmak gerekirse Haskell’e kıyasla beni daha basit kod yazmaya zorladığı yönler var ve sonuç çoğu zaman daha iyi oluyor.
    Yine de F# insana Haskell gibi “usta işi” hissi vermiyor. Haskell’e benziyor ama son derece pragmatik. F# ile pek çok iş yapıyorum ve keyifle kullanıyorum; ama arada bir Haskell ile neden yürümedi diye buruk bir şekilde geriye bakıyorum.

    • Bunu duymak güzel. Fonksiyonel programlamaya yeni girdim ve F#’tan keyif alıyorum; kısa ve pratik odaklı olmasını seviyorum.
      Haskell kullanmayınca bir şey kaçırıyor muyum diye sık sık merak ediyordum, ama benim amaçlarım için muhtemelen öyle değil.
  • Haskell öğrenmek, uzaylı dili çözmeye çalışmak gibi. Sıradan if-else döngülerine ve basit değişken atamalarına alışkınsanız, kafanızın karışmasına hazır olun.
    monad bir uzay canavarı değil, tuhaf bir soyut kavram; ama kafanızı kaşıyıp hayattaki seçimlerinizi sorgulatabilir. Kütüphanelerde de gerekeni bulmak, yarı boş bir ikinci el eşya dükkânını karıştırmak gibi; dokümantasyonun yarısı da hiyeroglif gibi okunuyor.
    Performans da gerçek dünyada lazy evaluation yüzünden beklediğinizden fazla bellek yiyebilir ve neden yavaşladığını uzun süre düşünmenize yol açabilir. İş bulmak da Haskell’e tamamen odaklanmış çok niş bir şirket olmadığı sürece zor; debugging ise fonksiyonel hiyeroglif yığınının içinde iğne aramak gibi hissettiriyor.

  • Scala kullanıyorum ve iki dünyanın da en iyi yanlarını sunabildiğini düşünüyorum. Cebirsel olarak akıl yürütebiliyorsunuz; refactor sonrası derleniyorsa genelde çalışıyor.
    Type inference ve monad’lar da iyi çalışıyor, Java ekosisteminin avantajlarını da alıyorsunuz. İşler fazla anlaşılmaz hâle gelirse kuralları bozup Java’ya daha yakın kod da yazabiliyorsunuz. Başkalarının ne düşündüğünü merak ediyorum.

    • Aynı nedenlerle Scala kullanmaktan gerçekten keyif aldım. Gerektiğinde kaçış yolu var ve ekosistemi de büyük.
      Ama sbt insanı çıldırtıyor; geliştirme deneyiminde muhtemelen en sevmediğim kısım.
    • Katılıyorum. Emirsel/OOP koddan saf fonksiyonel stile yumuşak ve kademeli geçişe izin vermesi de güzel.
  • Haskell’in yönetiminden sorumlu olanlar ve bakımcıları, bu dilin gerçekten araştırma, deney ve akademik keşif için elverişli olmasını hedefliyor gibi görünüyor.
    Bu başlı başına sorun değil; ama bir noktada Haskell’i pratik ve kararlı bir araç olarak kullanmak isteyen programcıların çıkarlarıyla kaçınılmaz olarak çatışıyor. Gereken şey, deneysel ve en ileri uçtaki şeyleri ayrı bir iz olarak işaretleyebilme yeteneği gibi görünüyor. Bu bir pragma da olabilir, paket düzeyinde bir bildirim de; pakete bakınca onu içeri alıp almamak gerektiği anlaşılabilmeli.
    Böylece pratik odaklı geliştiriciler “biz yalnızca stable Haskell kullanıyoruz” gibi politikalar benimseyebilir. Haskell’in benimsenmesi fazla artarsa dilin atalete kapılıp en ileri kavramları zorlayamaz hâle geleceğini söyleyen “Avoid success at all costs” dinamiğini kabul etmekle birlikte, günlük geliştiricilerin daha sınırlı ve kararlı bir Haskell alt kümesinde kalabileceği resmî bir iz gerekiyor.

    • Doğru. Bu ilke A History of Haskell: Being Lazy with Class (2007) içinde temel ilkelerden biri olarak açıkça belirtiliyor. PDF doğrudan bağlantısı: https://www.microsoft.com/en-us/research/wp-content/uploads/...
    • Bu rolü Stackage üstleniyor. Stackage, birlikte derlendiği ve testlerden geçtiği bilinen tutarlı Haskell paket kümeleri sağlar; bunlar Stackage Nightly snapshot’ları ve LTS (Long Term Support) sürümleri olur.
      Java asla böyle bir şeye sahip olmayacak. https://www.stackage.org/
    • Bu yönü teşvik eden Simple Haskell inisiyatifi var. Ancak “bu proje simple Haskell kullanıyor” demeyi sağlayan bir flag ya da pragma yok.
      Sadelik nihayetinde bakan kişiye göre değişir. Gösterişli tip özellikleri bile, nasıl çalıştıklarını içselleştirdiyseniz, tipleri daha ifade gücü yüksek hâle getiren, kodu daha güvenli ve hatta daha basit kılan kullanım alanlarına sahiptir.
  • Oldukça iyi bir yazı. Ancak zayıf yanı, istemiyorsanız belirli yeni ve gösterişli tip özelliklerini kullanmaya itilmiş gibi bir baskı hissetmemiş olmam.
    Servant’ın tip düzeyi HTTP API’sinden hoşlanmıyorsanız bir katman aşağı inip warp kullanabilirsiniz. Kütüphaneler, aşırı karmaşık tiplerin bir tuzak olabileceğini anlıyor; bu yüzden çoğu zaman bu şekilde katmanlandırılıyorlar. Nereye kadar gidilmesi gerektiğine dair bir sezgi gerekiyor ve bu süreç hataları da içeriyor

    • Haskell’i pek bilmeyen ama Servant fikrinin inanılmaz iyi göründüğünü düşünen biri için “lütfen bana öğretin” türünde iyi bir yazı bilen var mı merak ediyorum.
      Servant dokümantasyonunu okudum ama doğal olarak benim sahip olduğumdan daha fazla Haskell bilgisi varsayıyordu
  • Bu yazı gerçekten bana dokundu. Yaklaşık 1,5 yıldır oldukça endüstriyel bir uygulamada Haskell kullanıyorum; ondan önce de https://github.com/mattgreen/hython gibi epey deneyimim olmuştu.
    20 yıllık kariyerimde uzun zamandır ilk kez bu kadar çok şey öğrenmem gerekti; bu, alan ile dilin birleşiminin sonucu. Heyecan verici ama yorucu ve yoğun bir aile yaşamıyla birlikte taşınması oldukça büyük bir yük de olabiliyor.
    Yine de dil mükemmel. Yöneticim çoğunlukla top-down bir şekilde kullanmamı öneriyor; yani Haskell’in esnekliği geliştirme niyetini iyi aktardığı için nasıl okunması gerektiğini derinlemesine düşün ve oradan başla demek istiyor. Çoğu dilde function yazıp dururken beynin güç tasarrufu moduna geçmesine kıyasla büyük bir zihniyet değişimi ve gerçekten yazma dostu olacak şekilde tasarlanmış gibi hissettiriyor.
    Ancak kontrollü efektleri monad ile ele alsanız bile söz dizimini göz gezdirerek okumak hâlâ zor. Belki de bir satırın fazla yoğunlaşabilmesinden kaynaklanıyordur. Erken dönüşü çok özlüyorum, Rust’ın harika LSP’sini de özlüyorum. Haskell, 9.x iç değişiklikleri nedeniyle pattern match’leri doldurma özelliğini de yakın zamanda kaybetti; monad’ları üst üste yığmaktan hâlâ nefret ediyorum ve sık sık hata yapıyorum. Derleme süreleri, özellikle lens kütüphanesiyle karşılaşınca acımasız olabiliyor.
    Varsayılan olan lazy evaluation da hoşuma gitmiyor. Topluluk da Haskell programlarının bu varsayılan yüzünden space leak’lere çok daha yatkın olduğunu ve bunun birçok programda oldukça uzun süre fark edilmeyebileceğini bir ölçüde kabul etmiş durumda. Bir sistem programcısı olarak çığlık attırıyor.
    Yine de topluluk, gördüğüm en güçlü programcı topluluklarından biri. Bir meme gibi zeki olduklarına dair laflar sıralamak istemiyorum; asıl mesele gerçekten derin düşünüp ileri itmeleri. Bizim alanımız olan program analizi için Haskell eldiven gibi uyuyor, ama bunun dışındaki alanlarda hâlâ biraz temkinliyim. Özünde OCaml olan ama söz dizimi daha iyi bir programlama diline hâlâ susamış durumdayım

    • Okunabilirlik için erken dönüşün gerçekten gerekli olduğu zamanlar oluyor. Böyle durumlarda ExceptT kullanmanızı öneririm: https://www.stackage.org/haddock/lts-21.8/mtl-2.2.2/Control-...
      Arayüzde ExceptT’yi açığa çıkarmanız da gerekmez; içeride yalnızca erken dönüş için kullanıp fonksiyonun Either döndürmesini sağlayabilirsiniz
    • “OCaml ama söz dizimi daha iyi bir programlama dili” isteyen tek kişi değilsiniz. Ben de öyleyim; bu yüzden Reason ilk çıktığında derinlemesine incelemiştim.
      Sonunda ciddi bir traction yakalayamaması üzücü
    • O dil Scala 3. Python’a benzer bir söz dizimi var ve JVM sayesinde Haskell ya da OCaml’den çok daha büyük bir kütüphane ekosistemine sahip.
      Nesne yönelimli ve fonksiyonel programlamanın entegrasyonu OCaml’den daha iyi; idiomatik OCaml kodu da basit bir dönüşümle taşınabilecek kadar benzer