2 poin oleh GN⁺ 2023-08-26 | 1 komentar | Bagikan ke WhatsApp
  • 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 dari double x menjadi x + x selalu benar dalam Haskell
    • Dalam banyak bahasa imperatif, double(i++) dan (i++) + (i++) bisa berperilaku berbeda
      • Yang pertama menaikkan i satu kali
      • Yang kedua menaikkan i dua kali
    • 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 NonEmpty merepresentasikan list dengan setidaknya satu elemen
      • Operasi yang mempertahankan panjang seperti map mengembalikan NonEmpty
      • Operasi yang menambah panjang seperti append juga mengembalikan NonEmpty
      • Operasi seperti filter, yang hasilnya bisa kosong, mengembalikan list biasa
    • 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 RawString dan SanitizedString
      • Bahkan jika web API memberikan RawString, lapisan database bisa dibuat hanya menerima SanitizedString
    • Representasi permukaan yang memiliki banyak field Maybe bisa 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 ormolu yang 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 do juga merupakan fitur yang sangat dirindukan
    • Intinya bukan hanya pada do itu sendiri, melainkan pada sintaks yang tidak terus menambah tingkat indentasi walaupun binding baru ditambahkan
    • flat_map bertingkat di Ruby menjadi makin dalam setiap kali sumbu bertambah
    • Notasi do di Haskell mengekspresikan komposisi yang sama secara datar
  • Notasi do juga memungkinkan embedding struktur seperti konkurensi terstruktur bergaya async/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

 
GN⁺ 2023-08-26
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

    • Saya sudah mencoba berbagai bahasa, tetapi tooling Haskell termasuk yang paling buruk. language server sering rusak karena error acak, dan setiap kali saya bingung apakah manajemen versi Haskell harus diserahkan ke ghcup atau stack
      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
    • Cargo berevolusi dari ide lama seperti Bundler milik Ruby, jadi untuk alat semacam ini silsilahnya cukup panjang
      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
    • Agak sulit dipercaya bahwa tooling Java masuk kategori “kurang bagus”. Banyak hal negatif bisa dikatakan tentang Java itu sendiri, tetapi tooling gratis maupun komersialnya berada di level yang tak tertandingi
    • Tooling Haskell membuat saya kehilangan niat untuk mendalaminya lagi dengan serius. Sebaliknya, Purescript memberi pengalaman yang cukup mulus setiap kali saya mencobanya beberapa kali, terutama jika sudah terbiasa dengan tooling JS
    • Saya penasaran mengapa bahasa .NET atau Swift tidak muncul dalam pembahasan tooling. Mungkin karena IDE seperti Visual Studio atau Xcode adalah alat kelas satu, atau mungkin karena dunia open source cenderung menghindari ketergantungan pada big tech
  • 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 Result dan Box, 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 ada

    • Saya sangat setuju bahwa Hoogle sangat berguna. Namun untuk tooling lain, saya memakai haskell-language-server setiap hari, dan produktivitas saya jauh meningkat
      Belum sempurna, tetapi jauh lebih baik dibanding 5 tahun lalu
    • Hoogle benar-benar hebat. Terinspirasi dari sana, saya juga mengimplementasikan hal serupa untuk library functional programming C++ FunctionalPlus: https://www.editgym.com/fplus-api-search/
      Saya berharap lebih banyak proyek mengambil arah seperti ini
  • Menurut saya masalah terbesar adalah GHC terikat pada versi base tertentu, yaitu standard library-nya
    Ketika base berubah 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 memakai base 4.18.0.0. Mengapa binary GHC harus peduli pada versi modul Data.List dari kode yang menjadi target kompilasi
    Saya paham bahwa elemen khusus GHC yang diekspos base terikat pada versi GHC tertentu, tetapi saya tidak tahu apakah sisanya juga harus begitu. Namun saya memahami bahwa pekerjaan untuk memecah base menjadi beberapa paket sedang berlangsung demi memperbaiki hal ini: https://gitlab.haskell.org/ghc/ghc-wiki-mirror/-/blob/master...

    • Ada petunjuk di bagian yang dikutip. GHC yang lebih baru bisa menolak kode base lama sebagai tidak valid
    • Karena tipe data internal bisa berbeda. Jika library yang ditautkan ke implementasi base berbeda saling mengoper instance Data.List, itu akan menimbulkan masalah
      Misalnya, ketika ada list dari Data.List, apakah hasil dari dua fungsi library yang berbeda bisa Anda sambungkan ke list itu
    • Seperti yang disebutkan, base yang 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 diperbaiki
  • Jika 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

    • Dalam upaya putus asa untuk keluar dari penjara, para tahanan menerima ritual ganjil yang terinspirasi oleh cahaya yang terlihat di sela-sela jeruji sempit, dan menodai bahasa mereka sendiri
      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
    • Struktur data immutable yang efisien lebih penting bagi pemrograman fungsional daripada sebagian besar fitur yang disebutkan. Apa yang ditawarkan Java di sana
    • Saya tidak tahu bahwa komunitas berpindah dari Cabal ke Stack lalu kembali lagi ke Cabal. Saya sudah beberapa tahun meninggalkan Haskell, dan saat terakhir memakainya, Stack terasa paling mulus dan tampak menyelesaikan banyak rasa sakit Cabal
      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

    • Senang melihat cerita seperti ini. Saya baru masuk ke pemrograman fungsional dan menikmati F#, karena ringkas dan berorientasi praktik
      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

    • Saya sangat menikmati Scala karena alasan yang sama. Ada jalan keluar bila diperlukan, dan ekosistemnya besar
      Namun sbt membuat frustrasi, dan mungkin itu bagian yang paling tidak saya sukai dari pengalaman pengembangannya
    • Setuju. Saya juga suka karena ia memungkinkan transisi bertahap yang mulus dari kode imperatif/OOP ke gaya fungsional murni
  • 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

    • Benar. Prinsip ini disebutkan sebagai prinsip inti dalam A History of Haskell: Being Lazy with Class(2007). Tautan langsung PDF: https://www.microsoft.com/en-us/research/wp-content/uploads/...
    • Peran itu dijalankan oleh Stackage. Stackage menyediakan kumpulan paket Haskell yang konsisten, yang diketahui dapat dibangun bersama dan lolos pengujian, lalu menjadi snapshot Stackage Nightly dan rilis LTS(Long Term Support)
      Java tidak akan pernah mendapatkan hal seperti ini. https://www.stackage.org/
    • Ada inisiatif Simple Haskell yang mendorong arah seperti itu. Namun tidak ada flag atau pragma untuk mengatakan “proyek ini memakai simple Haskell”
      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 tidak begitu paham Haskell, tetapi penasaran apakah ada tulisan bagus bergaya “tolong ajari saya” untuk orang yang menganggap ide Servant terlihat luar biasa bagus.
      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 function berulang-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

    • Ada kalanya early return memang diperlukan demi keterbacaan. Untuk kasus seperti ini, saya menyarankan memakai ExceptT: https://www.stackage.org/haddock/lts-21.8/mtl-2.2.2/Control-...
      Tidak perlu mengekspos ExceptT di antarmuka; cukup pakai secara internal hanya untuk early return, lalu buat fungsi mengembalikan Either
    • Anda bukan satu-satunya yang menginginkan “bahasa pemrograman seperti OCaml tetapi dengan sintaks yang lebih baik”. Saya juga begitu, dan karena itu saya mendalami Reason saat pertama kali muncul.
      Sayang akhirnya tidak mendapat traction besar
    • Itu adalah Scala 3. Sintaksnya mirip Python, dan berkat JVM, ekosistem pustakanya jauh lebih besar daripada Haskell atau OCaml.
      Integrasi pemrograman berorientasi objek dan fungsionalnya lebih baik daripada OCaml, dan kode OCaml yang idiomatis cukup mirip sehingga mudah dipindahkan dengan transformasi sederhana