H-E-B’nin kurumsal Haskell benimsemesi ve işletimi
(blog.haskell.org)- 435’ten fazla mağaza ve lojistik merkezinin tedarik zincirini modernleştirme sürecinde Haskell benimsendi; 8 yıl sonra, birden fazla ekibin yönettiği yaklaşık 1 milyon satır kod kritik üretim sistemlerinde çalışıyor
- Haskell, çalışma zamanı hata türlerini azaltıyor ve GHC tabanlı refactoring ile legacy entegrasyonunu destekliyor; ancak SDK eksikliğinden kaynaklanan kendi bakım yükünü ve gelişmiş tip özelliklerinin karmaşıklığını üstlenmek gerekiyor
- Başarı, dilden çok ekip yetkinliği ve kültüre bağlıydı; Haskell uzmanı olmayan ekiplerdeki alan sızıntıları ve kilit geliştiricilerin ayrılması nedeniyle iki projede benimseme kalıcı olmadı
- GHC runtime, H-E-B’de hiçbir zaman üretim kesintilerinin nedeni olmadı; HLS, OpenTelemetry, profilleme gibi ekosistemlerin gelişmesiyle production Haskell rekabetçi bir seçenek hâline geldi
- Gelişmiş özellikleri küçük kütüphanelerin ve net arayüzlerin arkasında sınırlamak; test, gözlemlenebilirlik ve bilgi paylaşımıyla birlikte yürütmek gerekiyor. Coding agent çağında GHC’nin tip doğrulaması ve hızlı geri bildirimi daha da önemli hâle geliyor
Mainframe modernizasyonu görevi
- Teksas’ın en büyük halka açık olmayan şirketi olan perakendeci H-E-B’nin müşterileri, iç sistemlerden çok mağaza raflarında ürün olup olmadığıyla ilgileniyor
- On yıllar boyunca COBOL mainframe istikrarlı biçimde çalıştı; ancak son 10 yılda curbside pickup, eve teslimat, gerçek zamanlı stok ve mağaza içi arama gibi teknoloji odaklı özellikler ortaya çıktı
- 435’ten fazla mağaza ve bunları destekleyen lojistik merkezleriyle tedarik zinciri operasyonları ölçeklenirken, mevcut çekirdek sistemler ilk tasarlandıkları kapsamın ötesinde taleplerle karşılaştı
- Mainframe modernizasyonundaki asıl zorluk kodu buluta taşımak değil, on yıllar boyunca legacy iş mantığında birikmiş kuruma özgü bilgiyi korumaktır
- Yüzlerce tabloyla çalışan bir monoliti, otonom mühendislik ekiplerinin sahip olduğu mikroservislere bölmek teknik ve politik olarak devasa, ayrıca maliyetli bir iştir
Haskell benimsemesi ve işletim ölçeği
- Danışmanlar, şirketteki en büyük mainframe uygulamasının yerini alacak yeni proje için ortak dil olarak Haskell önerdi
- Deney olarak başlayan çalışma, birden fazla kritik tedarik zinciri üretim sistemine dönüştü
- Benimsemeden 8 yıl sonra, farklı alanlardaki birden fazla ekip yaklaşık 1 milyon satıra ulaşan Haskell kodunun bakımını yapıyor
- Uzun süreli production işletimi, gerçek kazanımların yanı sıra teknik ve organizasyonel zorlukları da ortaya çıkardı
İş açısından elde edilen avantajlar
- Şirketlerin istediği şey lazy evaluation, saf fonksiyonlar veya immutable verinin kendisi değil; 40 yıl boyunca null pointer exception olmadan, düşük bakım maliyetiyle çalışacak yeni nesil COBOL benzeri sistemlerdir
- Haskell uygulamaları, imperative ve dinamik tipli programlarda yaygın olan çalışma zamanı hata türlerini varsayılan olarak ortadan kaldırır
- Hatalar tamamen yok olmaz; ancak geriye kalan sorunlar null pointer exception veya tip karışıklığından çok iş mantığı hatalarına odaklanır
- Yıllara yayılan strangler fig yaklaşımıyla legacy geçişinde GHC güvenli refactoring’i destekler
- Gereksinimler şekillenirken tekrarlı biçimde değişiklik yapılabildiği için geçiş, waterfall yerine agile biçimde gerçekleştirilebilir
- Şirketler, yanlış biçimde donmuş çıktılara peşin yatırım yapmak yerine sonuçları kademeli olarak ölçebilir
- Haskell parser’ları, sabit genişlikli IBM copybook gibi binlerce satırlık legacy formatları doğrudan sözleşme olarak kullanmayı sağlar
- Güçlü foreign function interface (FFI) sayesinde yalnızca C kütüphanesi sunan mevcut servislerle de entegrasyon kurulabilir
- H-E-B,
simdjsonC++, OracleODPI-Cve IBM MQ’yu saran Haskell kütüphaneleri yazdı
- H-E-B,
SDK eksikliği ve sözleşme sahipliği
- Haskell SDK’ları yetersiz olduğunda, gereken client ve entegrasyon kodunu kendiniz oluşturup sürekli bakımını yapmanız gerekir
- Bunun karşılığında sözleşmenin doğrudan sahibi olur, tedarikçi bağımlılığından kaçınır ve üst proje yöneticisinin düzeltmeleri yayımlamasını beklemek zorunda kalmazsınız
- H-E-B, kritik bağımlılıklar için bu değiş tokuşun yeterince değerli olduğuna karar verdi
- Coding agent’lar, Go kütüphanelerini Haskell’e taşıma gibi mekanik işleri iyi yaparak diller arası geliştirme hızı farkını azaltabilir
- Ancak basit çeviri, özenli prompt’lar olmadan Haskell tip sisteminin avantajlarından tam olarak yararlanamayabilir
Gömülü DSL ile çok dilli entegrasyon
- Haskell, gömülü DSL (eDSL) için host dil olarak güçlüdür
- Merkezi bir ekip domain modelini veya iş mantığını bir kez tanımladıktan sonra, diğer ekiplerin kullandığı dillerde güvenli tipli kod üretebilir
- Diğer ekipler Haskell’i doğrudan yazmadan da ilgili sistemle entegre olabilir
- Hydra, Uber’in graf veri çalışmalarından gelişen açık kaynaklı bir DSL framework’üdür
- Haskell’de bootstrap edilir ve Java, Python, Scala gibi diller için anlamsal olarak eşdeğer implementasyonlar üretir
- Ortak test suite’i, dil bazlı implementasyonların eşdeğerliğini garanti eder
- H-E-B, hassas finansal hesaplamaların Haskell, TypeScript ve Java ekipleri arasında paylaşılabilmesini sağlayan bir Haskell DSL’inin prototipini oluşturuyor
- Çift yönlü bir JSON şema DSL’i de kurdu
- autodocodec ile benzerdir; ancak kullanıcıların kendi type class’larıyla çekirdek semantiği genişletebilmesini sağlayan tagless final encoding kullanır
- Şema sürüm yönetimi ile dokümantasyon, OpenAPI üretimi, regresyon ve golden testleri standartlaştırır
- Geçici interpreter’lar yazarak JSON şemasını PostgreSQL tablo tanımlarına dönüştürebilir veya
aesonyerinesimdjsonkullanıp ek doğrulama uygulayabilir
İşe alım ve mühendislik kültürü
- Modern diller de Haskell’den etkilenmiş pek çok tip güvenliği, saflık ve eşzamanlılık özelliği sunduğundan, pratikteki fark dilin teşvik ettiği mühendislik kültüründe yatar
- Haskell, doğruluğa ve soyutlama tasarımına önem veren geliştiricileri çeker
- Haskell rolleri için işe alım, yönetimin tahmin ettiği kadar zor olmadı
- Tedarik zincirine özel ilgisi olmasa bile yalnızca Haskell nedeniyle başvuran adaylar vardı
Karmaşıklık bütçesinin sınırları
- Haskell eski bir dildir ve çeşitli kusurları vardır; bu yüzden güncel GHC sürümlerini takip etmek önemlidir
- Ekipte uzman yoksa, tek bir dilsel kusur tüm projeye yayılabilir
- İlk dönemde deneyimli danışmanlar, dil uzantılarının ve kullanıcı tanımlı operatörlerin aşırı kullanımını engelleyen guardrail’ler oluşturdu
- GHC2021 ve GHC2024 dil edisyonlarının olmadığı dönemde, her ekip varsayılan uzantı setini kendisi yönetti
- Bu, yeni çalışanların katkı yapmadan önce öğrenmesi gereken dil kapsamını sınırlayan bir karmaşıklık bütçesi işlevi gördü
- Bağımlılıklar da karmaşıklık bütçesini tükettiği için organizasyon genelinde zorunlu kılmak zordur
servant, API’leri tip seviyesinde bir DSL olarak ifade eder; kullanıcı tanımlı combinator genişletmeleri type family’ler ve anlaşılması güç hatalarla birlikte gelirhaxl, eşzamanlı işleri toplu işlemek için tüm veri kaynaklarını sonuç tipiyle indekslenmiş GADT olarak modeller
- Geliştiriciler ustalaştıkça GADT, type family, generic, tagless final, arrow, free structure ve higher-kinded data type kalıplarını devreye alma cazibesi artar
- Zaten karmaşık olan iş domain’inin üzerine bu kavramlar eklendiğinde kolay bakım vaadi zayıflar
- Ekosisteme alışıldıkça gelişmiş özellikler kademeli olarak arttığı için karmaşıklık artışı geç fark edilebilir
Sıkıcı Haskell’in işletim ilkeleri
- Organizasyon düzeyinde sıkıcı Haskell önermek kolay, zorunlu kılmak zordur
- Gelişmiş Haskell’i makul arayüzlerin arkasına kapsüllerseniz etki alanını daraltır, karmaşıklık bütçesini az sayıda uzmanın yönettiği küçük kütüphanelerle sınırlayabilirsiniz
- Dil seviyesindeki karmaşıklık yalnızca Haskell’e özgü değildir; ancak Haskell’in kullanılabilir gelişmiş araç yelpazesi özellikle geniştir
- Kod satırı sayısı veya token kullanımı yerine, bir sonraki GHC yükseltmesinde ne kadar kodun kırıldığı Haskell projesinin karmaşıklığını daha iyi gösterir
Kalıcı olamayan iki proje
- Haskell bir ekibin yetkinliğini artırırken başka bir ekip için bariyer olabilir; H-E-B’de de iki projede farklı nedenlerle yerleşemedi
- İlk örnekte, Haskell deneyimi olmayan yetkin geliştiriciler başka bir ekibin proje şablonlarını ve teamüllerini izledi; ancak space leak nedeniyle tüm program durdu
- Güçlü bir Haskell geliştiricisi ekibe yol gösteremediği için bu tek sorun projenin durmasına yol açtı
- İkinci örnekte, Haskell’i destekleyen ve uygulamayı oluşturan mühendisler öncelik değişiklikleri nedeniyle başka projelere geçti
- Bu, dilin kendisiyle ilgili olmayan bir nedendi
- Her iki ekibin de mevcut teknolojiye dönme alternatifi vardı ve Haskell’in üretkenliği artırdığına ikna olamadılar
- Spring Boot şablonu gibi bir çıkış yolu varsa, zorlu bir space leak’i sonuna kadar teşhis etme motivasyonu zayıflayabilir
- LLM’lerin tüm codebase’i mekanik olarak çevirebilir hâle gelmesiyle yeniden yazma seçenekleri daha da genişliyor
- Uzun vadeli savunma hattı, yeniden yazılması zor olacak kadar zeki kod değil; Haskell’i sürdürmek isteyen ekiplerdir
Production kesintileri ve teşhis
- Haskell’i benimseyen ekiplerde de çeşitli ciddi sorunlar yaşandı
- Kullanıcı tanımlı referans sayımında double-free hatası oluştu
- Bir projede kontrolden çıkan space leak’i çözmek için paralel garbage collection devre dışı bırakıldı
- Sonsuz döngü, keşfetmesi bile zor olduğu için özellikle korkulan bir bug’dı
- GHC runtime, H-E-B’deki production kesintilerinin kök nedeni hiç olmadı
- Kararlı durumdaki throughput ve bellek kullanımı, H-E-B iş yüklerinde yeterince rekabetçiydi; sorun örnekleri genel durum değil istisnaydı
- Mühendisler segmentation fault core dump’larını, garbage collection metriklerini ve heap profillerini izleyerek sorunları çözdü
- Güçlü tip sistemi gerekçesiyle test kapsamından ödün verilmemeli
- Haskell uygulamalarında basit hata türleri derleme aşamasında elendiğinden, chaos engineering gerçek mantık ve kaynak arızalarını daha doğrudan ortaya çıkarabilir
Değişen geliştirme araçları ve ekosistem
- İlk sistemler GHC 8.2 ile başladı; o dönemde popüler platformlar için API client’larının ve SDK’ların çoğunu kendileri yazmak zorundaydılar
- Haskell Language Server yoktu, GHCup yeni ortaya çıkıyordu ve runtime profilleme de zordu
- Java IDE’lerine alışkın geliştiriciler Haskell araç ortamını rahatsız edici buldu; H-E-B, VS Code kullanıcıları için Debug Adapter Protocol desteği geliştirilmesine de sponsor oldu
- Bugün production seviyesinde Haskell geliştirme, yalnızca mümkün olmanın ötesinde rekabetçi bir seviyeye geldi
- Geliştirme araçları arasında HLS,
ghcid,ghciwatch,static-ls, tricorder ve editör eklentileri bulunuyor- Bazıları zengin GHCi odaklı geliştirme için GHC plugin’lerini kullanırken, bazıları VS Code ve HLS kullanıyor
- Geliştiricilerin tercih ettikleri araçları seçebilmesi sağlanıyor
- Gözlemlenebilirlik için
hs-opentelemetryve opentelemetry-auto kullanılıyoropentelemetry-auto, Haskell fonksiyonlarına OTel span’larını otomatik ekleyen bir GHC plugin’idir- Java ve Python’la kıyaslanabilir bir instrumentation ortamı sunabilir
Production kütüphaneleri ve runtime iyileştirmeleri
- Servisler
warp,aeson,attoparsec,stm,conduit,servant, orville-postgresql gibi kütüphaneleri kullanıyor - Ekosistemde gereken işlev yoksa kendi kütüphanelerini geliştiriyorlar
- arbiter, H-E-B çalışmasından çıkan transaction tabanlı bir PostgreSQL iş kuyruğudur ve şu anda production’da çalışıyor
- GHC, runtime teşhisi, derleyici performansı, eventlog streaming gibi izleme özellikleri ve exception annotation alanlarında iyileştirmeler yapıyor
- GHC 9.2’de info table profiling geldikten sonra space leak konusundaki endişeler büyük ölçüde azaldı
İç topluluk ve bilginin dağıtılması
- H-E-B, iç kütüphaneleri önemli görür ve geliştiricilerin hem şirket içi projelere hem de açık kaynak projelere katılmasını teşvik eder
- Yıllar boyunca iki haftada bir Haskell buluşmaları düzenleyerek mühendislerin keşiflerini paylaşmasını ve diğer üyeleri eğitmesini sağladı
- Kurumsal organizasyonlarda silo’ları azaltmak için ekipler arasında fikir ve kalıpların dolaşması gerekir
- Daha fazla mühendisin codebase’i okuyup sahiplenmesini sağlamak, tek bir kişinin ayrılmasının projeyi sarsacağı bus factor riskini azaltabilir
Gelişmiş özelliklere izin verme ölçütleri
- Gevşek temel kurallar koyulur; ancak karmaşıklık bütçesinin nerede harcanacağına teknik lider son kararı verir
- Saklanan kişisel tanımlanabilir bilgilerin (PII) şifrelenmesi gerekiyorsa, hassas veri sızıntısını runtime kazası değil derleme hatası hâline getiren tip seviyesi garantiler yatırıma değer olabilir
- Dört API sözleşmesini trees-that-grow kalıbıyla birleştirmek, dış şemayı type family’lerle gizleyecek kadar değerli olmayabilir
- Sıkıcı Haskell, tip seviyesi programlamayı veya gelişmiş GHC özelliklerini yasaklamaz; ilkeli teamüller belirler ve sapmanın maliyetini değerlendirir
- Başlıca teamül “uzakta beklenmedik etki yok”tur
TemplateHaskellkod üretimi veGenerictabanlı serialization mantığından kaçınılır- Boilerplate elle yazılarak davranış programcıya açıkça gösterilir
- quasiquoter veya
Genericallyile deriving tamamen yasaklanmaz
- Web formlarına tip seviyesinde state machine uygularken veya sıradan ADT’nin yeterli olduğu yerde GADT kullanırken sağlıklı şüphe ve ekip düzeyinde itiraz gerekir
- Gelişmiş Haskell hem kütüphanelerde hem de production uygulamalarında vardır; ancak deneylerin kapsamı sınırlandırılmalıdır
- İş ile teknik oyun arasındaki dengeyi ayarlama sürecinde gerçek mühendislik gerçekleşir
Haskell’in geleceği ve coding agent’lar
- Yıllar boyunca GHC kullanırken az sayıda bug bulunup raporlandı; ancak işi durduracak ölçüde sorun yaşanmadı
- Production kazaları nadirdir ve tip hatalarından veya runtime’dan çok iş mantığında ortaya çıkar
- Coding agent’ların yazdığı kod oranı arttıkça darboğaz kod yazmaktan doğrulamaya kayıyor
- GHC’nin tip sistemi, insanların güvenle refactoring yapmasına yardım ederken agent’ların halüsinasyonla ürettiği kodu çalıştırmadan önce reddeden hızlı geri bildirim döngüsü sağlar
- Haskell’in endüstrideki potansiyelini genişletmek için gerçek production başarı hikâyelerinin daha fazla paylaşılması gerekiyor
1 yorum
Lobste.rs görüşleri
Teksas dışında pek bilinmeyebilir ama H-E-B, Teksas’ın simgesel kurumlarından biri; ölçeği ve etkisi o kadar büyük ki eyalet yönetiminin bir başka kurumu gibi bile sayılabilir
Birçok mağazada tortilla üretim tesisi var ve büyük ölçekli üretime rağmen kalitesi de harika. Üstelik Haskell de kullanıyorlar
H-E-B gibi bir şirketin COBOL’ün yerini almak için Haskell’i seçmiş olması gerçekten şaşırtıcı
Kodlama ajanlarının Go kütüphanelerini mekanik biçimde Haskell’e taşıyabildiği için geliştirme hızı farkının azaldığını söylerken, hemen ardından akıllıca promptlar olmadan tip sisteminden yeterince yararlanılamayacağını kabul eden bu iki cümle, birbiriyle çelişen bir sorunu ortaya koyuyor
Buna karşılık, önemsiz hataların derleme aşamasında elenmesi sayesinde kaos mühendisliği ile altyapı arızaları enjekte edildiğinde, dinamik tipli dillerdeki gürültü yerine gerçek mantık ve kaynak hatalarının ortaya çıkması, Haskell’i değerlendirmek için en ikna edici neden gibi görünüyor
Geçen hafta Bazel’de izole Haskell build yapılandırmaya çalıştım ama doğrudan kullanılabilir bir çözüm bulamadım
rules_haskellvarsayılan olarak izole değil ve yaygın yaklaşımınnixpkgse ciddi biçimde dayandığı görülüyor. Görünüşe göre Haskell sistemin C++ linker’ına bağımlı; bunun bugünkü gerçek durum olup olmadığını ya da benim kaçırdığım bir alternatif bulunup bulunmadığını merak ediyorum