Cara yang diberikan kepada saya, dan apa yang menurut saya benar setelah belajar di Haskell selama sebulan sekarang, adalah fakta bahwa pemrograman fungsional memelintir otak Anda dengan cara yang menarik: hal itu memaksa Anda untuk memikirkan masalah yang sudah dikenal dengan cara yang berbeda : alih-alih loop, pikirkan di peta dan lipatan dan filter, dll. Secara umum, jika Anda memiliki lebih dari satu perspektif tentang suatu masalah, itu membuat Anda lebih mampu untuk bernalar tentang masalah ini, dan beralih sudut pandang jika perlu.
Hal lain yang benar-benar rapi tentang Haskell adalah sistem tipenya. Ini diketik dengan ketat, tetapi mesin inferensi tipe membuatnya terasa seperti program Python yang secara ajaib memberi tahu Anda ketika Anda telah melakukan kesalahan terkait tipe yang bodoh. Pesan kesalahan Haskell dalam hal ini agak kurang, tetapi ketika Anda lebih mengenal bahasa yang akan Anda katakan kepada diri sendiri: inilah yang seharusnya mengetik!
Ini adalah yang contoh yang meyakinkan saya untuk belajar Haskell (dan anak saya senang saya lakukan).
Oke, ini adalah program yang pendek dan dapat dibaca. Dalam hal ini lebih baik daripada program C. Tetapi apa bedanya dengan (katakanlah) program Python dengan struktur yang sangat mirip?
Jawabannya adalah evaluasi malas. Di sebagian besar bahasa (bahkan beberapa yang fungsional), program yang terstruktur seperti di atas akan mengakibatkan seluruh file dimuat ke memori, dan kemudian ditulis lagi dengan nama baru.
Haskell itu "malas". Itu tidak menghitung sesuatu sampai dibutuhkan, dan dengan ekstensi tidak menghitung hal-hal yang tidak pernah dibutuhkannya. Misalnya, jika Anda menghapus
writeFile
baris, Haskell tidak akan repot-repot membaca apa pun dari file tersebut.Karena itu, Haskell menyadari bahwa file
writeFile
bergantung padareadFile
, dan karenanya mampu mengoptimalkan jalur data ini.Meskipun hasilnya bergantung pada kompiler, yang biasanya akan terjadi saat Anda menjalankan program di atas adalah ini: program membaca blok (katakanlah 8KB) dari file pertama, lalu menulisnya ke file kedua, lalu membaca blok lain dari yang pertama file, dan menulisnya ke file kedua, dan seterusnya. (Coba lari
strace
di atasnya!)... yang terlihat sangat mirip dengan implementasi C efisien dari salinan file yang akan dilakukan.
Jadi, Haskell memungkinkan Anda menulis program yang ringkas dan dapat dibaca - seringkali tanpa mengorbankan banyak kinerja.
Hal lain yang harus saya tambahkan adalah bahwa Haskell mempersulit penulisan program buggy. Sistem tipe yang luar biasa, kurangnya efek samping, dan tentu saja kekompakan kode Haskell mengurangi bug setidaknya untuk tiga alasan:
Desain program yang lebih baik. Kompleksitas yang berkurang menyebabkan lebih sedikit kesalahan logika.
Kode kompak. Lebih sedikit baris untuk bug berada.
Mengompilasi kesalahan. Banyak bug yang bukan Haskell yang valid .
Haskell bukan untuk semua orang. Tetapi setiap orang harus mencobanya.
sumber
hSetBuffering handle (BlockBuffering (Just bufferSize))
.Data.Bytestring.Lazy.readFile
), yang tidak ada hubungannya dengan Haskell sebagai bahasa malas (non-ketat). Monads adalah sequencing - berarti ini kira-kira "semua efek samping dilakukan ketika Anda mengambil hasilnya". Adapun sihir "Lazy Bytestring": ini berbahaya, dan Anda dapat melakukannya dengan sintaks yang serupa atau lebih sederhana di sebagian besar bahasa lain.readFile
juga melakukan IO malas dengan cara yang samaData.ByteString.Lazy.readFile
. Jadi jawabannya tidak salah, dan ini bukan sekedar optimasi compiler. Memang, ini adalah bagian dari spesifikasi untuk Haskell : "readFile
Fungsi membaca file dan mengembalikan konten file sebagai string. File dibaca dengan malas, sesuai permintaan, seperti halnyagetContents
."const fs = require('fs'); const [file1, file2] = process.argv.slice(2); fs.createReadStream(file1).pipe(fs.createWriteStream(file2))
. Bash memiliki sesuatu yang serupa juga:cat $1 > $2
Anda semacam mengajukan pertanyaan yang salah.
Haskell bukanlah bahasa di mana Anda melihat beberapa contoh keren dan berkata "aha, saya mengerti sekarang, itulah yang membuatnya bagus!"
Ini lebih seperti, kita memiliki semua bahasa pemrograman lain, dan semuanya kurang lebih mirip, dan kemudian ada Haskell yang sama sekali berbeda dan aneh dengan cara yang benar-benar luar biasa setelah Anda terbiasa dengan keanehan. Namun masalahnya, perlu waktu cukup lama untuk menyesuaikan diri dengan keanehan tersebut. Hal-hal yang membedakan Haskell dari hampir semua bahasa lain yang bahkan semi-mainstream:
serta beberapa aspek lain yang berbeda dari banyak bahasa utama (tetapi dimiliki oleh beberapa orang):
Seperti yang telah dijawab oleh beberapa poster lain, kombinasi dari semua fitur ini berarti Anda berpikir tentang pemrograman dengan cara yang sama sekali berbeda. Jadi sulit untuk memberikan contoh (atau sekumpulan contoh) yang cukup mengkomunikasikan hal ini kepada Joe-mainstream-programmer. Itu adalah pengalaman. (Sebagai analogi, saya dapat menunjukkan foto perjalanan saya tahun 1970 ke China, tetapi setelah melihat foto-foto itu, Anda masih tidak akan tahu bagaimana rasanya tinggal di sana selama waktu itu. Demikian pula, saya dapat menunjukkan kepada Anda sebuah Haskell 'quicksort', tapi kamu masih belum tahu apa artinya menjadi Haskeller.)
sumber
Apa yang benar-benar membedakan Haskell adalah upaya yang dilakukan dalam desainnya untuk menerapkan pemrograman fungsional. Anda dapat memprogram dalam gaya fungsional dalam hampir semua bahasa, tetapi terlalu mudah untuk ditinggalkan begitu saja. Haskell tidak mengizinkan Anda untuk meninggalkan pemrograman fungsional, jadi Anda harus mengambil kesimpulan logisnya, yang merupakan program terakhir yang lebih mudah untuk dipikirkan, dan menghindari seluruh kelas dari jenis bug yang paling sulit.
Dalam hal menulis program untuk penggunaan dunia nyata, Anda mungkin menemukan Haskell kurang praktis, tetapi solusi akhir Anda akan lebih baik karena telah mengenal Haskell sejak awal. Saya jelas belum sampai di sana, tapi sejauh ini belajar Haskell jauh lebih mencerahkan daripada mengatakan, Lisp masih kuliah.
sumber
unsafePerformIO
untuk orang yang hanya ingin melihat dunia terbakar;)Bagian dari keributan adalah bahwa kemurnian dan pengetikan statis memungkinkan paralelisme dikombinasikan dengan optimisasi agresif. Bahasa paralel sedang panas sekarang dengan multicore menjadi sedikit mengganggu.
Haskell memberi Anda lebih banyak opsi untuk paralelisme daripada hampir semua bahasa tujuan umum, bersama dengan kompiler kode asli yang cepat. Sebenarnya tidak ada persaingan dengan jenis dukungan ini untuk gaya paralel:
Jadi jika Anda peduli tentang membuat multicore berfungsi, Haskell ingin mengatakan sesuatu. Tempat yang bagus untuk memulai adalah dengan tutorial Simon Peyton Jones tentang pemrograman paralel dan bersamaan di Haskell .
sumber
Software Transactional Memory adalah cara yang cukup keren untuk menangani konkurensi. Ini jauh lebih fleksibel daripada penyampaian pesan, dan tidak rawan kebuntuan seperti mutex. Penerapan STM oleh GHC dianggap salah satu yang terbaik.
sumber
Saya telah menghabiskan tahun lalu mempelajari Haskell dan menulis proyek yang cukup besar dan kompleks di dalamnya. (Proyek ini adalah sistem perdagangan opsi otomatis, dan segala sesuatu mulai dari algoritme perdagangan hingga penguraian dan penanganan umpan data pasar berkecepatan tinggi tingkat rendah dilakukan di Haskell.) Ini jauh lebih ringkas dan lebih mudah dipahami (bagi mereka yang memiliki latar belakang yang sesuai) daripada versi Java, dan juga sangat kuat.
Mungkin kemenangan terbesar bagi saya adalah kemampuan untuk memodulasi aliran kontrol melalui hal-hal seperti monoid, monad, dan sebagainya. Contoh yang sangat sederhana adalah Monoid Ordering; dalam ekspresi seperti
di mana
c1
dan seterusnya kembaliLT
,EQ
atauGT
,c1
kembaliEQ
menyebabkan ekspresi berlanjut, mengevaluasic2
; jikac2
kembaliLT
atauGT
itulah nilai keseluruhan, danc3
tidak dievaluasi. Hal semacam ini menjadi jauh lebih canggih dan kompleks dalam hal-hal seperti generator dan parser pesan monadik di mana saya mungkin membawa berbagai jenis status, memiliki berbagai kondisi pembatalan, atau mungkin ingin dapat memutuskan untuk panggilan tertentu apakah benar-benar membatalkan "tidak ada pemrosesan lebih lanjut" atau artinya, "mengembalikan kesalahan di akhir, tetapi melanjutkan pemrosesan untuk mengumpulkan pesan kesalahan lebih lanjut."Semua ini membutuhkan waktu dan upaya untuk mempelajarinya, dan karenanya akan sulit untuk membuat argumen yang meyakinkan untuk itu bagi mereka yang belum mengetahui teknik ini. Saya pikir tutorial All About Monads memberikan demonstrasi yang cukup mengesankan dari satu aspek ini, tetapi saya tidak berharap bahwa siapa pun yang tidak terbiasa dengan materi akan "mendapatkannya" pada bacaan pertama, atau bahkan ketiga, dengan cermat.
Bagaimanapun, ada banyak hal bagus lainnya di Haskell juga, tapi ini adalah hal utama yang tidak terlalu sering saya lihat, mungkin karena agak rumit.
sumber
Untuk contoh yang menarik, Anda dapat melihat: http://en.literateprograms.org/Quicksort_(Haskell)
Yang menarik adalah melihat implementasinya dalam berbagai bahasa.
Apa yang membuat Haskell begitu menarik, bersama dengan bahasa fungsional lainnya, adalah kenyataan bahwa Anda harus berpikir secara berbeda tentang bagaimana membuat program. Misalnya, Anda biasanya tidak akan menggunakan for atau while loop, tetapi akan menggunakan rekursi.
Seperti disebutkan di atas, Haskell dan bahasa fungsional lainnya unggul dengan pemrosesan paralel dan aplikasi penulisan untuk bekerja pada multi-core.
sumber
Saya tidak bisa memberi Anda contoh, saya seorang pria OCaml, tetapi ketika saya berada dalam situasi seperti Anda, rasa ingin tahu terus berlanjut dan saya harus mengunduh kompiler / juru bahasa dan mencobanya. Anda mungkin akan belajar lebih banyak dengan cara itu tentang kekuatan dan kelemahan bahasa fungsional tertentu.
sumber
Satu hal yang saya anggap sangat keren ketika berhadapan dengan algoritma atau masalah matematika adalah evaluasi malas Haskell yang melekat pada komputasi, yang hanya mungkin karena sifat fungsionalnya yang ketat.
Misalnya, jika Anda ingin menghitung semua bilangan prima, Anda dapat menggunakan
dan hasilnya sebenarnya adalah daftar yang tak terbatas. Tetapi Haskell akan mengevaluasinya dari kiri dari kanan, jadi selama Anda tidak mencoba melakukan sesuatu yang memerlukan seluruh daftar, Anda masih dapat menggunakannya tanpa program macet di tak terhingga, seperti:
yang menjumlahkan semua bilangan prima kurang dari 100. Ini bagus karena beberapa alasan. Pertama-tama, saya hanya perlu menulis satu fungsi prima yang menghasilkan semua bilangan prima dan kemudian saya cukup siap untuk bekerja dengan bilangan prima. Dalam bahasa pemrograman berorientasi objek, saya memerlukan beberapa cara untuk memberi tahu fungsi berapa banyak bilangan prima yang harus dihitung sebelum kembali, atau meniru perilaku daftar tak terbatas dengan objek. Hal lain adalah bahwa secara umum, Anda akhirnya menulis kode yang mengekspresikan apa yang ingin Anda hitung dan bukan dalam urutan mana untuk mengevaluasi sesuatu - sebaliknya compiler yang melakukannya untuk Anda.
Ini tidak hanya berguna untuk daftar yang tidak terbatas, pada kenyataannya ini digunakan tanpa Anda menyadarinya setiap saat ketika tidak perlu mengevaluasi lebih dari yang diperlukan.
sumber
Saya setuju dengan orang lain bahwa melihat beberapa contoh kecil bukanlah cara terbaik untuk memamerkan Haskell. Tapi aku akan tetap memberikannya. Berikut adalah solusi secepat kilat untuk masalah Proyek Euler 18 dan 67 , yang meminta Anda untuk menemukan jalur jumlah maksimum dari alas ke puncak segitiga:
Berikut adalah implementasi algoritme BubbleSearch yang lengkap dan dapat digunakan kembali oleh Lesh dan Mitzenmacher. Saya menggunakannya untuk mengemas file media besar untuk penyimpanan arsip di DVD tanpa limbah:
Saya yakin kode ini terlihat seperti omong kosong acak. Tetapi jika Anda membaca entri blog Mitzenmacher dan memahami algoritme, Anda akan kagum bahwa algoritme dapat dikemas ke dalam kode tanpa mengatakan apa pun tentang apa yang Anda cari.
Setelah memberi Anda beberapa contoh seperti yang Anda minta, saya akan mengatakan bahwa cara terbaik untuk mulai menghargai Haskell adalah dengan membaca makalah yang memberi saya ide-ide yang saya perlukan untuk menulis pengemas DVD: Why Functional Programming Matters oleh John Hughes. Makalah ini sebenarnya sudah ada sebelum Haskell, tetapi dengan cemerlang menjelaskan beberapa ide yang membuat orang menyukai Haskell.
sumber
Bagi saya, daya tarik Haskell adalah janji compiler yang dijamin benar. Bahkan jika itu untuk bagian murni dari kode.
Saya telah menulis banyak kode simulasi ilmiah, dan bertanya-tanya begitu banyak kali jika ada bug dalam kode saya sebelumnya, yang bisa membatalkan banyak pekerjaan saat ini.
sumber
Saya menemukan bahwa untuk tugas-tugas tertentu saya sangat produktif dengan Haskell.
Alasannya karena sintaks yang ringkas dan kemudahan pengujian.
Seperti inilah sintaks deklarasi fungsi:
Itu adalah cara paling sederhana yang bisa saya pikirkan untuk mendefinisikan suatu fungsi.
Jika saya menulis kebalikannya
Saya dapat memeriksa bahwa ini adalah kebalikan dari masukan acak dengan menulis
Dan menelepon dari baris perintah
Yang akan memeriksa bahwa semua properti di file saya dipegang, dengan menguji input secara acak ratusan kali.
Saya tidak berpikir Haskell adalah bahasa yang sempurna untuk semuanya, tetapi ketika menulis fungsi dan pengujian kecil, saya belum melihat yang lebih baik. Jika pemrograman Anda memiliki komponen matematika, ini sangat penting.
sumber
Jika Anda dapat memahami sistem tipe di Haskell, saya pikir itu sendiri sudah merupakan pencapaian yang cukup.
sumber
itu tidak memiliki konstruksi loop. tidak banyak bahasa yang memiliki ciri ini.
sumber
Saya setuju dengan mereka yang mengatakan bahwa pemrograman fungsional memelintir otak Anda untuk melihat pemrograman dari sudut yang berbeda. Saya hanya menggunakannya sebagai penghobi, tapi saya pikir itu secara mendasar mengubah cara saya mendekati suatu masalah. Saya rasa saya tidak akan seefektif LINQ tanpa terpapar Haskell (dan menggunakan generator dan pemahaman daftar dengan Python).
sumber
Untuk menyuarakan pandangan yang berlawanan: Steve Yegge menulis bahwa bahasa Hindely-Milner tidak memiliki fleksibilitas yang diperlukan untuk menulis sistem yang baik :
Haskell memang layak dipelajari, tetapi ia memiliki kelemahannya sendiri.
sumber