Adopsi dan Operasi Haskell Enterprise di H-E-B
(blog.haskell.org)- Haskell diadopsi dalam proses modernisasi rantai pasok untuk lebih dari 435 toko dan pusat distribusi, dan 8 tahun kemudian sekitar 1 juta baris kode yang dikelola oleh beberapa tim berjalan di sistem produksi inti
- Haskell mengurangi jenis error runtime dan mendukung refactoring berbasis GHC serta integrasi dengan sistem legacy, tetapi harus menerima pemeliharaan mandiri akibat kurangnya SDK dan kompleksitas fitur type tingkat lanjut
- Keberhasilan lebih banyak ditentukan oleh kapabilitas dan budaya tim daripada bahasa; karena kebocoran ruang pada tim tanpa pakar Haskell dan kepergian developer inti, adopsi tidak berhasil mengakar pada dua proyek
- Runtime GHC tidak pernah menjadi penyebab insiden produksi di H-E-B, dan seiring berkembangnya ekosistem seperti HLS, OpenTelemetry, dan profiling, Haskell produksi berubah menjadi pilihan yang kompetitif
- Fitur tingkat lanjut perlu dibatasi di balik library kecil dan interface yang jelas, disertai testing, observability, dan berbagi pengetahuan; di era coding agent, validasi type dari GHC dan feedback cepat menjadi semakin penting
Tantangan Modernisasi Mainframe
- Pelanggan H-E-B, retailer swasta terbesar di Texas, lebih peduli apakah rak toko terisi barang daripada sistem internalnya
- Selama puluhan tahun, mainframe COBOL berjalan dengan stabil, tetapi dalam 10 tahun terakhir muncul fitur-fitur berbasis teknologi seperti curbside pickup, pengiriman ke rumah, inventaris real-time, dan pencarian di dalam toko
- Saat operasi rantai pasok diperluas ke lebih dari 435 toko beserta pusat distribusi pendukungnya, sistem inti lama mulai menerima kebutuhan yang melampaui cakupan rancangan awalnya
- Kesulitan utama modernisasi mainframe bukan memindahkan kode ke cloud, melainkan mempertahankan pengetahuan khas organisasi yang telah terakumulasi selama puluhan tahun dalam business logic legacy
- Memecah monolit yang menangani ratusan tabel menjadi microservice yang dimiliki tim engineering otonom adalah pekerjaan yang sangat besar, mahal, serta kompleks secara teknis dan politis
Adopsi Haskell dan Skala Operasi
- Para konsultan mengusulkan Haskell sebagai bahasa umum untuk proyek baru yang menggantikan aplikasi mainframe terbesar di perusahaan
- Pekerjaan yang dimulai sebagai eksperimen berkembang menjadi beberapa sistem produksi rantai pasok inti
- Delapan tahun setelah adopsi, beberapa tim di berbagai domain memelihara sekitar 1 juta baris kode Haskell
- Operasi produksi jangka panjang mengungkap bukan hanya hasil nyata, tetapi juga kesulitan teknis dan organisasi
Manfaat bagi Bisnis
- Yang diinginkan perusahaan bukanlah lazy evaluation, pure function, atau immutable data itu sendiri, melainkan sistem seperti COBOL generasi berikutnya yang bisa berjalan selama 40 tahun tanpa null pointer exception dan dengan biaya pemeliharaan rendah
- Aplikasi Haskell secara default menghilangkan jenis error runtime yang umum pada program imperative dan dynamically typed
- Bug tidak sepenuhnya hilang, tetapi masalah yang tersisa lebih terfokus pada error business logic daripada null pointer exception atau kebingungan type
- Dalam migrasi legacy bertahun-tahun dengan pola strangler fig, GHC mendukung refactoring yang aman
- Kode dapat diperbaiki berulang kali saat requirement terbentuk, sehingga migrasi bisa dilakukan secara agile alih-alih waterfall
- Perusahaan dapat mengukur hasil secara bertahap, bukan membayar di muka untuk output yang telanjur mengeras secara keliru
- Parser Haskell memungkinkan format legacy sepanjang ribuan baris, seperti IBM copybook fixed-width, digunakan langsung sebagai kontrak
- Foreign Function Interface (FFI) yang kuat memungkinkan integrasi dengan layanan lama yang hanya menyediakan library C
- H-E-B menulis library Haskell yang membungkus
simdjsonC++, OracleODPI-C, dan IBM MQ
- H-E-B menulis library Haskell yang membungkus
Kekurangan SDK dan Kepemilikan Kontrak
- Jika SDK Haskell kurang tersedia, client dan kode integrasi yang diperlukan harus dibuat dan terus dipelihara sendiri
- Sebagai gantinya, kontrak dimiliki sendiri, vendor lock-in dapat dihindari, dan tidak perlu menunggu pengelola proyek upstream merilis perbaikan
- H-E-B menilai pertukaran ini cukup bernilai untuk dependensi inti
- Coding agent dapat menangani pekerjaan mekanis memindahkan library Go ke Haskell dengan baik, sehingga mengurangi selisih kecepatan pengembangan antarbahasa
- Namun, terjemahan sederhana mungkin tidak memanfaatkan keunggulan type system Haskell secara penuh tanpa prompt yang cermat
Integrasi Multibahasa melalui DSL Tertanam
- Haskell kuat sebagai host language untuk DSL tertanam (eDSL)
- Tim pusat dapat mendefinisikan domain model atau business logic sekali, lalu menghasilkannya sebagai kode type-safe dalam bahasa yang digunakan tim lain
- Tim lain dapat berintegrasi dengan sistem tersebut tanpa harus menulis Haskell secara langsung
- Hydra adalah framework DSL open-source yang berkembang dari pekerjaan data graf Uber
- Hydra di-bootstrap dari Haskell dan menghasilkan implementasi yang setara secara semantik untuk Java, Python, Scala, dan lainnya
- Shared test suite memastikan kesetaraan implementasi per bahasa
- H-E-B membuat prototipe DSL Haskell agar perhitungan keuangan sensitif dapat dibagikan oleh tim Haskell, TypeScript, dan Java
- Mereka juga membangun DSL skema JSON dua arah
- Mirip dengan autodocodec, tetapi menggunakan encoding tagless final yang memungkinkan pengguna memperluas semantik inti dengan type class mereka sendiri
- Ini menstandarkan versioning skema, dokumentasi, pembuatan OpenAPI, serta regression dan golden test
- Interpreter sementara dapat ditulis untuk mengubah skema JSON menjadi definisi tabel PostgreSQL, atau mengganti
aesondengansimdjsondan menerapkan validasi tambahan
Rekrutmen dan Budaya Engineering
- Bahasa modern juga menyediakan banyak fitur type safety, purity, dan concurrency yang dipengaruhi Haskell, sehingga perbedaan nyata terletak pada budaya engineering yang didorong oleh bahasa tersebut
- Haskell menarik developer yang mengutamakan correctness dan desain abstraksi
- Perekrutan untuk peran Haskell tidak sesulit perkiraan manajemen
- Ada kandidat yang melamar karena Haskell itu sendiri, meskipun tidak memiliki minat khusus pada rantai pasok
Batas Complexity Budget
- Haskell adalah bahasa lama dengan berbagai kekurangan, sehingga penting untuk mengikuti rilis GHC terbaru
- Jika tim tidak memiliki pakar, satu kekurangan bahasa dapat menyebar ke seluruh proyek
- Pada awalnya, konsultan berpengalaman membuat guardrail untuk mencegah penggunaan language extension dan operator kustom secara berlebihan
- Saat belum ada edisi bahasa GHC2021 dan GHC2024, setiap tim mengelola sendiri kumpulan extension dasar
- Ini berperan sebagai complexity budget yang membatasi cakupan bahasa yang harus dipelajari karyawan baru sebelum berkontribusi
- Dependensi itu sendiri juga menghabiskan complexity budget, sehingga sulit dipaksakan di tingkat organisasi
servantmerepresentasikan API sebagai DSL level type, dan perluasan combinator kustom disertai type family serta error yang sulit dipahamihaxlmemodelkan semua data source sebagai GADT yang diindeks oleh result type untuk melakukan batching pekerjaan concurrent
- Semakin mahir developer, semakin besar godaan untuk memperkenalkan pola GADT, type family, generic, tagless final, arrow, free structure, dan higher-kinded data type
- Jika konsep-konsep ini ditumpuk di atas domain bisnis yang sudah kompleks, janji pemeliharaan yang mudah menjadi melemah
- Karena fitur tingkat lanjut bertambah secara bertahap seiring meningkatnya keakraban dengan ekosistem, kenaikan kompleksitas bisa baru terlihat belakangan
Prinsip Operasi Haskell yang Membosankan
- Mendorong Haskell yang membosankan di tingkat organisasi memang mudah, tetapi menegakkannya sulit
- Dengan mengenkapsulasi Haskell tingkat lanjut di balik interface yang masuk akal, cakupan dampaknya dapat dikurangi, dan complexity budget bisa dibatasi pada library kecil yang dikelola segelintir pakar
- Kompleksitas di level bahasa bukan hanya masalah Haskell, tetapi Haskell memiliki rentang alat tingkat lanjut yang sangat luas
- Banyaknya kode yang rusak pada upgrade GHC berikutnya lebih baik menunjukkan kompleksitas proyek Haskell daripada jumlah baris kode atau penggunaan token
Dua Proyek yang Tidak Berhasil Mengakar
- Haskell dapat memperkuat kapabilitas satu tim sekaligus menjadi hambatan bagi tim lain, dan di H-E-B ada dua proyek yang tidak berhasil mengakar karena alasan berbeda
- Pada kasus pertama, developer berpengalaman tanpa pengalaman Haskell mengikuti template dan konvensi proyek tim lain, tetapi seluruh program terhenti akibat space leak
- Karena tidak ada developer Haskell yang kuat untuk membimbing tim, satu masalah ini berujung pada penghentian proyek
- Pada kasus kedua, para engineer yang mendukung Haskell dan membangun aplikasinya dipindahkan ke proyek lain karena perubahan prioritas
- Ini adalah alasan yang tidak terkait dengan bahasa itu sendiri
- Kedua tim memiliki opsi untuk kembali ke teknologi lama dan tidak yakin Haskell meningkatkan produktivitas
- Jika ada jalan keluar seperti template Spring Boot, motivasi untuk mendiagnosis space leak yang sulit hingga tuntas bisa melemah
- Seiring LLM mampu menerjemahkan seluruh codebase secara mekanis, opsi rewrite menjadi semakin luas
- Garis pertahanan jangka panjang bukanlah kode yang terlalu cerdas untuk ditulis ulang, melainkan tim yang ingin terus mempertahankan Haskell
Insiden Produksi dan Diagnosis
- Bahkan pada tim yang menerima Haskell, beberapa masalah serius tetap terjadi
- Terjadi error double-free pada reference counting kustom
- Pada satu proyek, parallel garbage collection dinonaktifkan untuk mengatasi space leak yang tak terkendali
- Infinite loop adalah bug yang sangat menakutkan karena sulit ditemukan
- Runtime GHC tidak pernah menjadi akar penyebab insiden produksi di H-E-B
- Throughput dan penggunaan memori dalam kondisi normal cukup kompetitif untuk workload H-E-B, dan contoh masalah tersebut adalah pengecualian, bukan situasi umum
- Para engineer memecahkan masalah dengan menelusuri core dump segmentation fault, metrik garbage collection, dan heap profile
- Type system yang kuat tidak boleh dijadikan alasan untuk mengorbankan test coverage
- Karena aplikasi Haskell menghilangkan jenis error sederhana pada tahap kompilasi, chaos engineering dapat menyingkap kegagalan logika dan resource nyata secara lebih langsung
Perubahan Tooling dan Ekosistem Pengembangan
- Sistem awal dimulai dengan GHC 8.2, dan saat itu sebagian besar API client dan SDK untuk platform populer harus ditulis sendiri
- Haskell Language Server belum ada, GHCup baru mulai muncul, dan runtime profiling juga sulit
- Developer yang terbiasa dengan Java IDE merasa lingkungan tooling Haskell tidak nyaman, dan H-E-B bahkan mensponsori pengembangan dukungan Debug Adapter Protocol untuk pengguna VS Code
- Saat ini, pengembangan Haskell kelas produksi telah berkembang melampaui sekadar memungkinkan, menjadi kompetitif
- Tooling pengembangan mencakup HLS,
ghcid,ghciwatch,static-ls, tricorder, dan plugin editor- Sebagian menggunakan plugin GHC untuk pengembangan kaya yang berpusat pada GHCi, sebagian lainnya menggunakan VS Code dan HLS
- Developer dapat memilih tool yang mereka sukai
- Untuk observability digunakan
hs-opentelemetrydan opentelemetry-autoopentelemetry-autoadalah plugin GHC yang otomatis menyisipkan OTel span ke fungsi Haskell- Dibandingkan Java dan Python, lingkungan instrumentation yang serupa dapat disediakan
Library Produksi dan Perbaikan Runtime
- Layanan menggunakan library seperti
warp,aeson,attoparsec,stm,conduit,servant, dan orville-postgresql - Jika fitur yang diperlukan tidak tersedia di ekosistem, mereka mengembangkan library sendiri
- arbiter adalah queue pekerjaan PostgreSQL berbasis transaksi yang lahir dari pekerjaan H-E-B dan saat ini berjalan di produksi
- GHC meningkatkan diagnostik runtime, performa compiler, fitur monitoring seperti eventlog streaming, dan exception annotation
- Setelah info table profiling diperkenalkan di GHC 9.2, kekhawatiran terhadap space leak jauh berkurang
Komunitas Internal dan Penyebaran Pengetahuan
- H-E-B memperlakukan library internal sebagai hal penting, dan mendorong developer berpartisipasi baik di proyek internal maupun open-source
- Selama bertahun-tahun mereka menjalankan pertemuan Haskell dua mingguan agar engineer dapat membagikan hasil eksplorasi dan mengedukasi anggota lain
- Untuk mengurangi silo dalam organisasi enterprise, ide dan pola harus mengalir antar tim
- Membuat lebih banyak engineer membaca dan memiliki codebase dapat menurunkan risiko bus factor ketika satu orang keluar dan mengguncang proyek
Kriteria untuk Mengizinkan Fitur Tingkat Lanjut
- Tetapkan aturan dasar yang longgar, tetapi tech lead membuat keputusan akhir tentang di mana complexity budget digunakan
- Jika informasi identitas pribadi (PII) yang disimpan harus dienkripsi, jaminan level type yang mengubah kebocoran data sensitif menjadi compile error alih-alih insiden runtime bisa layak diinvestasikan
- Menggabungkan empat kontrak API dengan pola trees-that-grow mungkin tidak cukup bernilai untuk menyembunyikan skema eksternal menggunakan type family
- Haskell yang membosankan tidak melarang type-level programming atau fitur GHC tingkat lanjut; ia menetapkan konvensi berprinsip lalu mengevaluasi biaya penyimpangan
- Konvensi utama adalah “tidak ada aksi tak terduga dari tempat yang jauh”
- Hindari code generation
TemplateHaskelldan logika serialisasi berbasisGeneric - Tulis boilerplate secara langsung agar programmer melihat perilakunya dengan eksplisit
- Deriving melalui quasiquoter atau
Genericallytidak sepenuhnya dilarang
- Hindari code generation
- Saat mengimplementasikan type-level state machine untuk web form, atau menggunakan GADT ketika ADT biasa sudah cukup, diperlukan kecurigaan yang sehat dan sanggahan di tingkat tim
- Haskell tingkat lanjut ada di library maupun aplikasi produksi, tetapi ruang lingkup eksperimen harus dibatasi
- Engineering nyata terjadi dalam proses menyeimbangkan pekerjaan dan permainan teknis
Masa Depan Haskell dan Coding Agent
- Selama bertahun-tahun menggunakan GHC, mereka menemukan dan melaporkan segelintir bug, tetapi tidak ada yang sampai menghentikan pekerjaan
- Insiden produksi jarang terjadi, dan jauh lebih sering berasal dari business logic daripada type error atau runtime
- Seiring porsi kode yang ditulis coding agent meningkat, bottleneck bergeser dari penulisan kode ke verifikasi
- Type system GHC membantu manusia melakukan refactoring dengan aman sekaligus menyediakan feedback loop cepat yang menolak kode halusinasi buatan agent sebelum dijalankan
- Untuk memperluas kemungkinan Haskell di industri, lebih banyak kisah sukses produksi nyata perlu dibagikan
1 komentar
Opini di Lobste.rs
Mungkin tidak begitu dikenal di luar Texas, tetapi H-E-B adalah institusi ikonis di Texas; skala dan pengaruhnya begitu besar hingga bisa dibilang seperti departemen lain dari pemerintah negara bagian.
Banyak gerainya memiliki fasilitas pembuatan tortilla, dan untuk produk skala besar, kualitasnya juga sangat baik. Selain itu, katanya mereka juga menggunakan Haskell.
Fakta bahwa perusahaan seperti H-E-B memilih Haskell untuk menggantikan COBOL benar-benar mengejutkan.
Dua kalimat yang mengatakan bahwa agen coding dapat memindahkan library Go ke Haskell secara mekanis sehingga selisih kecepatan pengembangan berkurang, lalu langsung mengakui bahwa tanpa prompt yang cerdas sistem tipe mungkin tidak dimanfaatkan secara memadai, menunjukkan masalah yang saling bertentangan.
Di sisi lain, karena kesalahan sepele dieliminasi pada tahap kompilasi, ketika kegagalan infrastruktur disuntikkan lewat chaos engineering, yang muncul bukan noise dari bahasa bertipe dinamis melainkan kesalahan logika dan sumber daya yang nyata; ini terdengar sebagai alasan paling meyakinkan untuk mempertimbangkan Haskell.
Minggu lalu saya mencoba mengonfigurasi build Haskell yang terisolasi di Bazel, tetapi tidak menemukan solusi yang langsung bisa dipakai.
rules_haskellpada dasarnya tidak terisolasi, dan pendekatan yang umum tampaknya sangat bergantung padanixpkgs. Sepertinya Haskell bergantung pada linker C++ sistem; saya penasaran apakah memang begitulah kondisi nyatanya saat ini, atau ada alternatif yang saya lewatkan.