Meninggalkan Haskell di Belakang
(journal.infinitenegativeutility.com)- Seorang programmer yang menggunakan Haskell sebagai bahasa utama dari sekitar 2009 hingga sekitar 2019 kini tidak lagi menempatkan Haskell sebagai pilihan default untuk proyek pribadi maupun pencarian kerja
- Daya tarik Haskell baginya bukan terutama pada monad atau DSL itu sendiri, melainkan pada penalaran kode secara aljabar serta kemampuan sistem tipe yang kuat untuk memungkinkan refactoring yang aman dan mengekspresikan invariant
- Alasan ia menjauh adalah akumulasi budaya yang menyukai fitur tipe tingkat lanjut, tooling yang kurang mulus, serta perubahan tidak kompatibel yang terus berlanjut pada GHC dan pustaka standar
- Meski begitu, fungsi orde tinggi, notasi
do, lens, pustaka deklaratif, dan abstraksi tipe tingkat lanjut tetap menjadi keunggulan yang sulit digantikan bahasa lain - Haskell sangat layak dipelajari untuk menjadi programmer yang lebih baik, tetapi menjadikannya bahasa default sebuah organisasi berarti harus menerima biaya dari kualitas tooling dan stabilitas bahasa
Masa ketika Haskell menjadi bahasa utama dan posisinya sekarang
- Selama sekitar 10 tahun, Haskell adalah bahasa default untuk proyek baru
- Setelah mengenal Haskell sekitar 2009, hingga pindah pada sekitar 2019 ke pekerjaan yang terutama memakai Ruby dan C++, penulis menganggap dirinya sebagai programmer Haskell
- Haskell digunakan untuk berbagai keperluan seperti alat baris perintah, layanan web, aplikasi grafis, dan skrip kecil
- Kini ia tidak sepenuhnya menolak Haskell, tetapi Haskell bukan lagi bahasa default bahkan untuk proyek pribadi, dan ia juga tidak lagi sengaja mencari “pekerjaan Haskell” seperti dulu
- Penilaian ini bukan kesimpulan bahwa Haskell itu buruk, melainkan lebih dekat pada alasan pribadi mengapa ia menjauh dari Haskell
Alasan Haskell begitu menarik
-
Sifat yang memungkinkan kode diperlakukan secara aljabar
- Daya tarik terbesar Haskell adalah bahwa kode bisa ditalar secara simbolik dan aljabar
- Misalnya, jika ada fungsi
double n = n + n, maka transformasi daridouble xmenjadix + xselalu benar dalam Haskell - Dalam banyak bahasa imperatif,
double(i++)dan(i++) + (i++)bisa berperilaku berbeda- Yang pertama menaikkan
isatu kali - Yang kedua menaikkan
idua kali
- Yang pertama menaikkan
- Sifat ini memungkinkan kita menumpuk transformasi mekanis kecil untuk melakukan refactoring besar dengan lebih aman
- Refactoring besar pada codebase Ruby bisa sangat menegangkan, tetapi pada codebase Haskell hal itu bisa jauh lebih mudah
-
Sistem tipe yang ketat namun tidak terlalu berisik
- Sistem tipe Haskell itu ketat, tetapi berkat type inference, penulisan anotasi tipe tidak berlebihan seperti di Java
- Typeclass juga mengurangi kerepotan saat harus memperhatikan tipe
- Kode Haskell yang baik memiliki sifat “rapuh dengan cara yang baik” (
brittle)- Abstraksi yang salah tidak diam-diam melengkung hingga membiarkan program yang keliru lolos
- Jika ada masalah, kompilasi gagal
- Tipe
NonEmptymerepresentasikan list dengan setidaknya satu elemen- Operasi yang mempertahankan panjang seperti
mapmengembalikanNonEmpty - Operasi yang menambah panjang seperti
appendjuga mengembalikanNonEmpty - Operasi seperti
filter, yang hasilnya bisa kosong, mengembalikan list biasa
- Operasi yang mempertahankan panjang seperti
- Jika sebuah fungsi mensyaratkan daftar path file bertipe
NonEmpty, argumen command line tidak bisa langsung diberikan; harus diperiksa dulu bahwa isinya tidak kosong - Jika kemudian ditambahkan tahap penyaringan ekstensi, hasilnya bisa kosong sehingga perlu diperiksa lagi, dan compiler akan mencegah jalur yang secara keliru mengirimkan list kosong
-
Cara menjaga invariant melalui tipe
- Setelah lama memakai Haskell, orang terbiasa mengekspresikan invariant program melalui tipe dan membiarkan compiler memverifikasinya
- Ini tidak hanya berarti perhitungan tingkat tipe yang rumit
- Status escape SQL bisa dibedakan dengan tipe pembungkus seperti
RawStringdanSanitizedString- Bahkan jika web API memberikan
RawString, lapisan database bisa dibuat hanya menerimaSanitizedString
- Bahkan jika web API memberikan
- Representasi permukaan yang memiliki banyak field
Maybebisa diubah menjadi representasi internal yang menjamin informasi yang dibutuhkan memang ada - Kita juga bisa membuat sesuatu cukup generik agar dapat diuji secara independen
-
Bahasa yang alami untuk DSL dan fungsi orde tinggi
- Haskell memudahkan pembuatan bahasa khusus domain yang ringkas bahkan tanpa macro
- config-ini adalah contoh pustaka untuk menangani file konfigurasi INI
- Ia memakai antarmuka deklaratif alih-alih antarmuka parsing imperatif
- Ia memetakan bagian tertentu dari tipe konfigurasi ke bagian tertentu dari struktur file INI
- Dengan antarmuka yang sama, ia bisa membaca, menulis, dan melakukan pembaruan minimal berbasis diff
- DSL Ruby bisa bergantung pada metaprogramming dinamis dan monkeypatching global, sedangkan DSL Haskell lebih mudah dibatasi pada file atau area kode tertentu berkat sintaks yang fleksibel dan fitur seperti overloading monad
- Haskell juga membuat kerja dengan fungsi orde tinggi terasa alami
(+)bisa langsung dipakai sebagai fungsi yang menerima dua angka dan menjumlahkannya- Ekspresi seperti
pairwiseProduct = zipWith (*)dapat menyatakan perkalian elemen demi elemen dari dua list dengan sangat singkat
- Analogi yang cocok adalah bahwa Haskell membuat kita memperlakukan fungsi seperti Perl memperlakukan string
Tiga faktor yang membuat menjauh dari Haskell
-
Suasana yang menyukai gaya yang rumit
- Faktor pertama adalah preferensi gaya terhadap hal baru yang canggih
- Komunitas Haskell terus bereksperimen dan membangun abstraksi baru
- Pendekatan yang diambil dari aljabar abstrak atau teori kategori
- Pendekatan yang menaikkan lebih banyak komputasi ke level tipe untuk membatasi keadaan yang salah
- API web tingkat tipe Servant atau contoh mengekspresikan sistem menu dengan comonad adalah eksperimen untuk merepresentasikan domain masalah dengan cara baru
- Namun dalam kode sehari-hari, pendekatan eksperimental semacam ini bisa menimbulkan lebih banyak masalah daripada manfaat yang tampak pada awalnya
- Dalam sebuah contoh proyek compiler, node AST memiliki tipe ekspresi sebagai parameter tipe
- Jika terbentuk syntax tree yang memiliki type error, compiler itu sendiri tidak akan bisa dikompilasi
- Pada awalnya pendekatan ini memang menangkap beberapa bug
- Tetapi ketika banyak pass optimisasi tidak cocok dengan disiplin tipe tersebut, kode menjadi rumit karena penuh cast dan upaya membujuk GHC
- Pada akhirnya, parameter tipe itu dihapus dari AST
- Dari proyek-proyek yang mencoba pendekatan “fancy types”, sekitar tiga perempat dinilai tidak memberi nilai yang cukup
- Arus Simple Haskell berangkat dari gagasan bahwa manfaat terbesar bahasa ini justru diperoleh saat menghindari fitur eksperimental dan tetap pada ekstensi minimum
- Fitur tipe yang lebih kompleks sudah tersebar luas dalam komunitas dan pustaka
- Abstraksi tipe yang kompleks bisa menyulitkan perubahan dan pemeliharaan, dan pernah ada pengalaman ketika upaya mengganti abstraksi yang sudah disederhanakan kembali ke abstraksi level tipe terbaru justru berujung pada pembesaran kode, penurunan performa, dan turunnya keterbacaan
- Meski begitu, fitur “fancy type-level” seperti Trees that Grow tetap menjadi contoh yang terasa berguna, misalnya untuk struktur data yang diindeks per tahap compiler
-
Tooling yang tidak menonjol dalam pekerjaan sehari-hari
- Faktor kedua adalah ekosistem tooling yang canggung
- Haskell punya beberapa sistem build dan alat pengembangan yang nyaris menjadi standar
- Alat-alat ini pada umumnya bisa melakukan hal yang dibutuhkan, tetapi belum mencapai tingkat yang “menyenangkan untuk dicintai”
- Ada alat seperti
ormoluyang menyelesaikan tugasnya dengan kerepotan minimal, tetapi beberapa alat lain memerlukan penanganan bug dan workaround yang terus-menerus - Tooling Haskell memang membaik selama 10 tahun, tetapi hingga 2019 belum ada alat yang mendekati kemudahan pakai dan stabilitas Rust Cargo
- Kecenderungan Not-Invented-Here untuk terus membuat sesuatu yang baru dan dianggap lebih baik juga menjadi masalah
- Bahkan format teks paket pun ingin ditangani ulang dengan hpack
- Upaya seperti ini yang bertahun-tahun tertahan di level 95% selesai terasa melelahkan
- Ini bukan berarti tooling Haskell buruk sekali, tetapi “lumayan oke” tidak lagi memenuhi standar yang sudah meningkat
-
Perubahan tidak kompatibel yang terus berlanjut
- Faktor ketiga adalah perubahan berkelanjutan yang dialami bahasa Haskell dan GHC
- GHC pada praktiknya diperlakukan sebagai satu-satunya implementasi Haskell terbuka yang masuk akal
- Haskell terus berupaya memperbaiki kesalahan dan ketidakkonsistenan masa lalu, bahkan pada pustaka standar dan bagian dasar bahasa
- Perubahan semacam ini memang bisa membawa bahasa menuju fondasi yang lebih bersih dan konsisten, tetapi bagi pengguna ia menimbulkan gesekan kecil yang terus-menerus
- Foldable-Traversable Prelude changes pada 2015 adalah contoh perubahan seperti itu
- Proyek Haskell lama bisa gagal dibangun dengan GHC terbaru bahkan tanpa dependensi eksternal
- penambahan superclass
- penghapusan import
- penambahan type signature karena polimorfisme menjadi ambigu
- Perbaikannya biasanya kecil, tetapi terus menumpuk, dan bagian-bagian yang kini sedikit berbeda dari dulu terus menuntut perhatian pengguna
- Sebagai pembanding, cara pembaruan epochs di Rust secara eksplisit menetapkan kontrak kompatibilitas mundur untuk fitur stabil dan menyembunyikan breaking change yang disengaja di balik epoch
Keunggulan Haskell yang masih dirindukan
- Penulisan kode dan refactoring secara aljabar di Haskell tetap menjadi kekuatan
- Rust juga berbagi banyak keunggulan dengan Haskell, tetapi keyakinan bahwa refactoring mekanis kecil akan mempertahankan makna program tidak semudah di Haskell
- Sistem tipenya juga tetap menyediakan kemampuan yang umumnya tidak dimiliki bahasa lain
- Bahasa arus utama pada 2023 telah berkembang jauh dalam fitur tipe statis dibanding 2009
- Namun fitur seperti abstraksi di atas higher-kinded types tetap menjadi pembeda Haskell
- Ekosistem pustaka Haskell bercampur aduk
- pustaka open source yang setengah terawat
- kerajaan-kerajaan kecil tempat masing-masing penulis membangun ulang dunianya sendiri
- tipe-tipe mirip string yang sama-sama diperlukan tetapi berbeda satu sama lain
- Meski begitu, Haskell tetap memiliki pustaka dan abstraksi hebat yang di bahasa lain hanya bisa dicapai setengah jalan
- Lens adalah abstraksi kuat yang manfaatnya tidak akan benar-benar terasa jika belum cukup banyak dipakai
- Brick menyediakan pustaka terminal UI yang sangat baik melalui blok-blok deklaratif
- diagrams dan music-suite juga merupakan contoh API deklaratif yang baik
- Notasi
dojuga merupakan fitur yang sangat dirindukan- Intinya bukan hanya pada
doitu sendiri, melainkan pada sintaks yang tidak terus menambah tingkat indentasi walaupun binding baru ditambahkan flat_mapbertingkat di Ruby menjadi makin dalam setiap kali sumbu bertambah- Notasi
dodi Haskell mengekspresikan komposisi yang sama secara datar
- Intinya bukan hanya pada
- Notasi
dojuga memungkinkan embedding struktur seperti konkurensi terstruktur bergayaasync/await, transaksi konkuren, dan program probabilistik dengan sintaks ringan yang sama
Haruskah mempelajari atau menggunakan Haskell?
- Jawaban untuk “haruskah mempelajari atau menggunakan bahasa ini” bergantung pada tujuan
- Jika tujuannya menjadi programmer yang lebih baik, Haskell sangat layak dipelajari
- Haskell adalah bahasa yang menarik dan kuat
- Pengalaman mempelajari Haskell dinilai telah meningkatkan kemampuan pemrograman
- Jika tujuannya adalah penggunaan nyata, perlu lebih berhati-hati
- Keunggulan Haskell memang nyata
- Namun itu perlu ditimbang dengan seberapa besar gesekan yang sanggup diterima individu atau organisasi seperti yang dijelaskan di atas
- Ada individu dan organisasi yang memperoleh manfaat cukup besar dari Haskell sehingga ketidaknyamanan kecil tetap hanya menjadi luka kecil
- Jika dipaksa memberi jawaban ya atau tidak secara tegas, jawabannya lebih dekat ke “jangan gunakan Haskell”
- Jika membangun organisasi engineering, penulis tidak akan menetapkan Haskell sebagai bahasa default
- Karena ia tahu nilai dari tooling yang baik sekaligus biaya dari tooling yang buruk
- Ia lebih memilih bahasa yang bisa segera menyediakan stabilitas, ekosistem kode yang jelas, dan tooling yang unggul
- Meski begitu, Haskell tetap menyediakan alat yang luar biasa untuk keamanan dan ketepatan program
- Dalam konteks tertentu, itu bisa sepadan dengan tooling yang buruk dan linting untuk mencegah type family yang tidak perlu
- Haskell bukan lagi bahasa yang secara pribadi paling cocok baginya, tetapi jika Haskell tidak pernah ada di dunia, dunia akan menjadi tempat yang lebih buruk
1 komentar
Opini Hacker News
Setelah memakai Haskell sekitar 10 tahun, belakangan saya keluar dari sana sebagai sumber penghidupan, dan saya jelas setuju dengan poin pertama penulis: komunitas Haskell sangat menekankan pembelajaran
Bekerja dengan orang-orang yang penuh rasa ingin tahu dan selalu ada hal untuk diajarkan serta dipelajari memang menyenangkan, tetapi komunitas ini cenderung lemah dalam membuang ide yang sudah dicoba. Akibatnya, codebase Haskell profesional, jika tidak dikelola dengan ketat, mudah menumpuk banyak “hal yang bisa dilakukan, tetapi sebaiknya tidak dipakai”
Namun soal toolchain, pendapat saya berbeda. Memang benar tooling Haskell kurang bagus, tetapi setelah mencoba Python, JS, Java, Rust, dan Elm, sebagian besar tooling juga kurang bagus, dan justru saya merindukan toolchain Haskell. cargo memang luar biasa, tetapi lebih seperti pengecualian, dan saya penasaran apakah Rust bisa tetap menghindari kondisi ini setelah menua
Ada proyek yang sesekali saya kerjakan, dan saya 100% yakin saat dibuka lagi nanti proyek itu tidak akan berjalan. Manajemen dependensi dan virtual environment Python juga sama buruknya, tetapi Poetry cukup bagus; Ruby berjalan sama baiknya mau memakai chruby/rbenv/rvm, dan Bundler juga bekerja dengan baik. Java punya kekurangan, tetapi pengalaman IDE-nya kelas atas, dan meski refactoring tidak seaman di Haskell, itu bisa dilakukan dengan sangat mudah
Bundler pada umumnya tidak buruk, dan meski ada pilihan desain yang tidak saya setujui, jika mengikuti jalur yang benar banyak hal akan pas dengan sendirinya. Tooling bahasa juga bisa dibuat dengan cara yang cukup tidak rusak, dan walau saya belum banyak memakai cargo secara langsung, jika memang benar terbaik di kelasnya, saya tidak akan terkejut bila kondisinya tetap bertahan
Dari sisi tooling, sejauh yang saya tahu Haskell punya satu hal yang sulit ditandingi bahasa lain: Hoogle
Hoogle luar biasa bagus. Jika Anda mengatakan apa yang Anda inginkan dalam Haskell, ia memberi tahu apa yang bisa Anda lakukan dengan Haskell. Di Rust pernah ada upaya serupa, dan saya juga pernah mencoba membuat Noogle untuk Nim, tetapi pada bahasa yang membedakan dengan jelas antara “meneruskan argumen ke fungsi” dan “memanggil fungsi”, pendekatan yang sama tidak bekerja
Setiap kali melihat kode Rust yang melibatkan
ResultdanBox, saya berharap ada Roogle yang sama bergunanya seperti Hoogle. Selain itu, tooling Haskell tidak punya keunggulan. Sebagian besar tampaknya karena naluri komunitas yang ingin membuat sesuatu yang “inovatif” alih-alih memperbaiki yang sudah adaBelum sempurna, tetapi jauh lebih baik dibanding 5 tahun lalu
Saya berharap lebih banyak proyek mengambil arah seperti ini
Menurut saya masalah terbesar adalah GHC terikat pada versi
basetertentu, yaitu standard library-nyaKetika
baseberubah dan versi GHC baru hanya mendukung versi itu, pada praktiknya kita harus mengubah semua dependensi agar bisa memakai GHC yang lebih baru. Saya masih belum paham mengapa kode yang dikompilasi dengan GHC 9.6 harus memakaibase4.18.0.0. Mengapa binary GHC harus peduli pada versi modulData.Listdari kode yang menjadi target kompilasiSaya paham bahwa elemen khusus GHC yang diekspos
baseterikat pada versi GHC tertentu, tetapi saya tidak tahu apakah sisanya juga harus begitu. Namun saya memahami bahwa pekerjaan untuk memecahbasemenjadi beberapa paket sedang berlangsung demi memperbaiki hal ini: https://gitlab.haskell.org/ghc/ghc-wiki-mirror/-/blob/master...baselama sebagai tidak validbaseberbeda saling mengoper instanceData.List, itu akan menimbulkan masalahMisalnya, ketika ada list dari
Data.List, apakah hasil dari dua fungsi library yang berbeda bisa Anda sambungkan ke list itubaseyang bisa diinstal ulang adalah tujuan yang diinginkan semua orang. Situasi saat ini banyak disebabkan alasan historis dan karena elemen dasar yang terikat ke internal compiler digabungkan dengan elemen non-dasar; dengan usaha yang cukup, ini bisa diperbaikiJika ada tiga alasan besar mengapa minat terhadap Haskell makin memudar, itu adalah preferensi gaya terhadap hal baru yang memuji kode sulit dipahami sehingga menyulitkan pemeliharaan, tooling yang canggung dan membuat pekerjaan sehari-hari terasa lebih lamban, serta perubahan berkelanjutan yang kadang-kadang tetapi konsisten harus diperhatikan dan secara berkala merusak sesuatu
Itu kritik yang valid. Saya banyak belajar Haskell pada 2010–2012; bahasanya sendiri bagus, tetapi dokumentasi dan tooling-nya sulit ditangani. Komunitas berpindah dari Cabal dan Cabal hell yang terkenal buruk ke Stack, lalu kembali lagi ke Cabal, dan secara umum memang membaik
Di sisi lain, bahasa pemrograman lain juga menyerap elemen pemrograman fungsional. Misalnya Java menambahkan Streams, fungsi, lambda, tipe data aljabar, records, dan pattern matching; meski sintaksnya tidak seelegan Haskell, konsep dasar pemrograman fungsional sudah ada di dalamnya
Dengan begitu mereka menciptakan lubang penderitaan tanpa akhir bagi diri mereka sendiri, dan itu hanya nyaris tertahankan karena berkas cahayanya tidak cukup rendah untuk melihat warna yang diciptakan cahaya pada pohon di luar jendela. Orang-orang dari luar dengan cepat kehilangan kewarasan, tercabik antara dialek yang disesuaikan dengan kegelapan buatan sendiri dan dialek yang dapat berkembang dalam cahaya tetapi tercekik di tempat itu
Jika komunitas kembali ke Cabal, saya penasaran apa yang terlewat oleh saya
Karena alasan-alasan ini saya pindah ke F# dan hampir tidak pernah menoleh ke belakang. Kadang saya memang merindukan higher-kinded types, tetapi F# juga punya generics, dan sejujurnya ada sisi yang memaksa saya menulis kode yang lebih sederhana daripada di Haskell, sehingga hasilnya umumnya lebih baik
Namun F# tidak memberi rasa “jagoan” seperti Haskell. Ia mirip Haskell, tetapi sangat pragmatis. Saya menyelesaikan banyak hal dengan F# dan senang menggunakannya, tetapi sesekali saya masih menoleh dengan sedikit nostalgia dan bertanya-tanya mengapa hubungan saya dengan Haskell tidak berhasil
Saya sering bertanya-tanya apakah saya melewatkan sesuatu jika tidak memakai Haskell, tetapi untuk tujuan saya mungkin tidak
Mempelajari Haskell terasa seperti mencoba memecahkan bahasa alien. Jika Anda terbiasa dengan loop if-else biasa dan assignment variabel sederhana, bersiaplah kepala Anda dibuat kusut
monad bukan monster luar angkasa, melainkan konsep abstrak yang aneh, yang bisa membuat Anda menggaruk kepala dan mempertanyakan pilihan hidup. Untuk library pun, mencari yang dibutuhkan terasa seperti mengaduk-aduk toko barang bekas yang setengah kosong, dan separuh dokumentasinya terbaca seperti hieroglif
Performa di dunia nyata juga bisa membuat Anda lama memikirkan mengapa program memakan memori lebih banyak dari perkiraan dan melambat karena lazy evaluation. Pekerjaan pun sulit ditemukan kecuali di perusahaan sangat niche yang all-in pada Haskell, dan debugging terasa seperti mencari jarum di tumpukan hieroglif fungsional
Saya sudah memakai Scala, dan menurut saya ia bisa memberi keunggulan dari dua dunia. Kita bisa bernalar secara aljabar, dan jika setelah refactoring kodenya berhasil dikompilasi, biasanya ia berjalan
Type inference dan monad juga bekerja dengan baik, plus mendapat manfaat ekosistem Java. Jika sesuatu menjadi terlalu sulit dipahami, kita juga bisa melanggar aturan dan menulis kode yang lebih dekat ke Java. Penasaran apa pendapat orang lain
Namun sbt membuat frustrasi, dan mungkin itu bagian yang paling tidak saya sukai dari pengalaman pengembangannya
Para pengelola dan maintainer Haskell tampaknya memang berniat agar bahasa ini ramah untuk riset, eksperimen, dan eksplorasi akademis
Itu sendiri tidak masalah, tetapi pada titik tertentu pasti berbenturan dengan kepentingan programmer yang ingin memakai Haskell sebagai alat yang praktis dan stabil. Yang dibutuhkan tampaknya kemampuan untuk menandai hal-hal eksperimental dan mutakhir sebagai jalur terpisah. Entah lewat pragma atau deklarasi tingkat paket, hanya dengan melihat paket seharusnya kita bisa tahu apakah akan menariknya masuk atau tidak
Dengan begitu, developer yang berorientasi praktik bisa mengadopsi kebijakan seperti “kami hanya memakai stable Haskell”. Sambil mengakui dinamika “Avoid success at all costs”, yaitu jika adopsi Haskell terlalu tinggi bahasa itu bisa terjebak inersia dan tidak mampu mendorong konsep mutakhir, tetap diperlukan jalur resmi agar developer sehari-hari bisa tetap berada pada subset Haskell yang lebih terbatas dan stabil
Java tidak akan pernah mendapatkan hal seperti ini. https://www.stackage.org/
Pada akhirnya, kesederhanaan bergantung pada siapa yang melihatnya. Fitur tipe yang mewah pun, jika cara kerjanya sudah diinternalisasi, punya kegunaan untuk membuat tipe lebih ekspresif, kode lebih aman, bahkan lebih sederhana
Tulisan yang cukup bagus. Namun bagian lemahnya adalah bahwa saya belum pernah merasa ditekan untuk memakai fitur tipe baru yang canggih dan mencolok tertentu jika memang tidak menginginkannya.
Jika tidak suka API HTTP level tipe milik Servant, kita bisa turun satu tingkat dan memakai warp. Pustaka-pustaka sering disusun berlapis seperti ini karena mereka memahami bahwa tipe yang terlalu rumit bisa menjadi jebakan. Memang perlu intuisi tentang sejauh mana harus melangkah, dan proses itu juga mencakup kesalahan
Saya sudah membaca dokumentasi Servant, tetapi tentu saja dokumentasi itu mengasumsikan pemahaman Haskell yang lebih banyak daripada yang saya miliki
Tulisan ini benar-benar terasa relevan. Saya sudah sekitar 1,5 tahun memakai Haskell untuk aplikasi yang cukup industrial, dan sebelumnya juga punya cukup banyak pengalaman seperti https://github.com/mattgreen/hython
Untuk pertama kalinya setelah lama dalam karier 20 tahun, saya harus belajar cukup banyak hal, dan itu hasil gabungan domain dan bahasanya. Menyenangkan sekaligus melelahkan, dan bisa jadi beban yang cukup besar untuk ditanggung bersama kehidupan keluarga yang sibuk.
Meski begitu, bahasanya luar biasa. Manajer saya umumnya menganjurkan untuk memakainya dengan pendekatan top-down; maksudnya, karena fleksibilitas Haskell dapat menyampaikan niat pengembangan dengan baik, pikirkan secara mendalam bagaimana kode seharusnya dibaca lalu mulai dari sana. Ini perubahan pola pikir besar dibandingkan mengetik
functionberulang-ulang di kebanyakan bahasa sampai otak masuk mode hemat daya, dan benar-benar terasa dirancang agar ramah untuk penulisan.Namun meski efek yang terkontrol ditangani dengan monad, sintaksnya tetap sulit dibaca sekilas. Entah apakah karena satu baris bisa menjadi terlalu padat. Saya sangat merindukan early return, dan juga LSP Rust yang sangat bagus. Haskell baru-baru ini juga kehilangan fitur pengisian pattern match karena perubahan internal 9.x, dan menumpuk monad tetap tidak saya sukai serta sering saya lakukan keliru. Waktu kompilasi bisa kejam, terutama saat bertemu pustaka lens.
Saya juga tidak suka lazy evaluation sebagai default. Komunitas pun sampai taraf tertentu sudah mengakui bahwa program Haskell jauh lebih rentan terhadap space leak karena default ini, dan pada banyak program hal itu bisa tidak terdeteksi cukup lama. Sebagai programmer sistem, ini membuat saya ingin berteriak.
Meski begitu, komunitasnya adalah salah satu kumpulan programmer terkuat yang pernah saya lihat. Saya tidak ingin sekadar mengulang meme bahwa mereka pintar; yang besar adalah mereka benar-benar berpikir mendalam dan mendorong batas ke depan. Untuk domain kami, analisis program, Haskell terasa sangat pas seperti sarung tangan, tetapi di area lain saya masih agak berhati-hati. Pada dasarnya saya masih haus akan bahasa pemrograman yang seperti OCaml tetapi dengan sintaks yang lebih baik
Tidak perlu mengekspos ExceptT di antarmuka; cukup pakai secara internal hanya untuk early return, lalu buat fungsi mengembalikan Either
Sayang akhirnya tidak mendapat traction besar
Integrasi pemrograman berorientasi objek dan fungsionalnya lebih baik daripada OCaml, dan kode OCaml yang idiomatis cukup mirip sehingga mudah dipindahkan dengan transformasi sederhana