Apa perbedaan antara Cabal dan Stack?

104

Kemarin saya belajar tentang alat Haskell baru yang disebut Stack . Pada blush pertama, sepertinya itu melakukan pekerjaan yang sama seperti Cabal. Lalu, apa perbedaan diantara keduanya? Apakah stack merupakan pengganti Cabal? Dalam kasus apa saya harus menggunakan Stack daripada Cabal? Apa yang bisa dilakukan Stack yang tidak bisa dilakukan Cabal?

ZhekaKozlov
sumber
fpcomplete.com/blog/2015/06/announcing-first-public-beta-stack (singkatnya itu semacam menggantikan cabal-installdan menggunakan tumpukan sebanyak mungkin - mungkin ada beberapa integrasi kembali ke cabal-install di beberapa titik dan saya pikir komunitas tidak yakin apakah ini hal yang baik atau tidak, karena dapat memecah komunitas)
Carsten
AFAIU stack berguna untuk mengerjakan proyek yang sudah ada dengan cepat. Jika Anda memulai sesuatu dari awal, Anda pasti harus menggunakan komplotan rahasia.
mb14
@ mb14 Bukan itu masalahnya. Anda dapat menggunakan tumpukan untuk memulai proyek dari awal. Faktanya, templat tumpukan menyediakan cara mudah untuk melakukannya.
Sibi
Lihat artikel singkat ini untuk ikhtisar yang baik: scs.stanford.edu/16wi-cs240h/labs/stack.html
michid

Jawaban:

76

Apakah stack merupakan pengganti Cabal?

Iya dan tidak.

Dalam kasus apa saya harus menggunakan Stack daripada Cabal? Apa yang bisa dilakukan Stack yang tidak bisa dilakukan Cabal?

Stack menggunakan paket tumpukan yang dikurasi secara default . Oleh karena itu, setiap dependensi diketahui dibangun bersama, menghindari masalah konflik versi (yang, dulu hal itu biasa terjadi dalam pengalaman Haskell, dulu dikenal sebagai "neraka komplotan rahasia"). Versi terbaru dari Cabal juga memiliki langkah-langkah untuk mencegah konflik. Namun, menyiapkan konfigurasi build yang dapat direproduksi di mana Anda tahu persis apa yang akan ditarik dari repositori lebih mudah dengan Stack. Perhatikan bahwa ada juga ketentuan untuk menggunakan paket non-tumpukan, jadi Anda dapat menggunakannya meskipun sebuah paket tidak ada dalam snapshot tumpukan.

Secara pribadi, saya suka Stack dan akan merekomendasikan setiap pengembang Haskell untuk menggunakannya. Perkembangan mereka cepat . Dan memiliki UX yang jauh lebih baik. Dan ada hal-hal yang Stack lakukan yang Cabal belum menyediakan:

  • Stack bahkan mengunduh GHC untuk Anda dan menyimpannya di lokasi yang terisolasi.
  • Dukungan Docker (yang sangat nyaman untuk menerapkan aplikasi Haskell Anda)
  • Skrip Haskell yang dapat direproduksi : Anda dapat menunjukkan versi paket dan mendapatkan jaminan bahwa paket akan selalu dijalankan tanpa masalah. ( Cabal juga memiliki fitur skrip , tetapi sepenuhnya memastikan reproduktifitas dengannya tidak sesederhana itu.)
  • Kemampuan untuk melakukan stack build --fast --file-watch. Ini akan secara otomatis membangun kembali jika Anda mengubah file lokal yang ada. Menggunakannya bersama dengan --pedanticopsi adalah pemecah kesepakatan bagi saya.
  • Stack mendukung pembuatan proyek menggunakan template . Ini juga mendukung templat khusus Anda sendiri.
  • Stack memiliki dukungan hpack built-in di dalamnya. Ini menyediakan cara alternatif (IMO, yang lebih baik) untuk menulis file komplotan rahasia menggunakan file yaml yang lebih banyak digunakan di industri.
  • Intero memiliki pengalaman yang mulus saat bekerja dengan Stack .

Ada posting blog bagus yang menjelaskan perbedaannya: Mengapa Stack bukan Cabal? Sementara Cabal, pada tahun-tahun berikutnya sejak pos itu, berevolusi untuk mengatasi beberapa masalah yang dibahas di sana, diskusi tentang tujuan desain dan filosofi di balik Stack tetap relevan.

Sibi
sumber
Apakah ada perubahan sejak cabal 3 dirilis?
William Rusnack
1
@WilliamRusnack Ya, ada. Terutama, alur kerja Cabal default sekarang menggabungkan penghindaran konflik ketergantungan, meskipun strategi yang digunakan untuk melakukannya sangat berbeda dari Stack. (@Sibi: Saya telah mengambil kebebasan untuk memperbarui jawaban Anda sehingga lebih mencerminkan di mana keadaan saat ini.)
duplode
35

Berikut ini, saya akan merujuk pada dua alat yang dibandingkan sebagai cabal-install dan stack . Secara khusus, saya akan menggunakan cabal-install untuk menghindari kebingungan dengan perpustakaan Cabal , yang merupakan infrastruktur umum yang digunakan oleh kedua alat.

Secara garis besar, kita dapat mengatakan cabal-install dan stack adalah frontend ke Cabal . Kedua alat memungkinkan untuk membangun proyek Haskell yang kumpulan dependensinya mungkin bertentangan satu sama lain dalam batasan satu sistem. Perbedaan utama di antara mereka terletak pada cara mereka menangani tujuan ini:

  • Secara default, cabal-install akan, ketika diminta untuk membangun sebuah proyek, melihat dependensi yang ditentukan dalam .cabalfilenya dan menggunakan pemecah ketergantungan untuk mencari tahu satu set paket dan versi paket yang memenuhinya. Set ini diambil dari Hackage secara keseluruhan - semua paket dan semua versi, dulu dan sekarang. Setelah rencana build yang layak ditemukan, versi dependensi yang dipilih akan diinstal dan diindeks dalam database di suatu tempat ~/.cabal. Konflik versi antar dependensi dapat dihindari dengan mengindeks paket yang diinstal sesuai dengan versinya (serta opsi konfigurasi lain yang relevan), sehingga project yang berbeda dapat mengambil versi dependensi yang mereka perlukan tanpa saling menginjak kaki satu sama lain. Pengaturan ini adalah apadokumentasi cabal-install berarti "build lokal bergaya Nix" .

  • Ketika diminta untuk membangun sebuah proyek, tumpukan akan, daripada pergi ke Hackage, lihat resolverbidang stack.yaml. Dalam alur kerja default, bidang tersebut menentukan snapshot Stackage , yang merupakan subset dari paket Hackage dengan versi tetap yang diketahui kompatibel satu sama lain. tumpukan maka akan berusaha untuk memenuhi dependensi ditentukan dalam berkas (atau mungkin para berkas - format yang berbeda, peran yang sama) hanya menggunakan apa yang disediakan oleh snapshot. Paket yang diinstal dari setiap snapshot terdaftar dalam database terpisah, yang tidak saling mengganggu..cabalproject.yaml

Kami mungkin mengatakan bahwa pendekatan stack memperdagangkan beberapa fleksibilitas penyiapan untuk kesederhanaan saat menentukan konfigurasi build. Secara khusus, jika Anda tahu bahwa proyek Anda menggunakan, katakanlah, snapshot LTS 15.3, Anda dapat membuka halaman Stackage dan mengetahui, sekilas, versi tumpukan dependensi apa pun yang mungkin diambil dari Stackage. Meskipun demikian, kedua alat menawarkan fitur yang melampaui alur kerja dasar sehingga, pada umumnya, masing-masing dapat melakukan semua yang dilakukan yang lain (meskipun mungkin dengan cara yang kurang nyaman). Misalnya, ada cara untuk membekukan versi yang tepat dari konfigurasi build yang dikenal baik dan untuk menyelesaikan dependensi dengan status lama Hackage dengan cabal -install, dan dimungkinkan untuk meminta dependensi non-Stackage atau mengganti versi paket snapshot saat menggunakan stack .

Terakhir, perbedaan lain antara cabal-install dan stack yang cukup besar untuk disebutkan dalam ikhtisar ini adalah bahwa stack bertujuan menyediakan lingkungan build yang lengkap, dengan fitur-fitur seperti manajemen instalasi GHC otomatis dan integrasi Docker . Sebaliknya, cabal-install dimaksudkan untuk menjadi ortogonal ke bagian lain dari ekosistem, dan karenanya tidak berusaha menyediakan fitur semacam ini (khususnya, versi GHC harus diinstal dan dikelola secara terpisah, baik itu melalui distro Linux paket, Haskell Platform Core di Windows, atau alat ghcup ).

duplode
sumber
11

Dari apa yang saya dapat dari FAQ, tampaknya Stack menggunakan perpustakaan Cabal, tetapi bukan cabal.exebiner (lebih dikenal sebagai cabal-install). Sepertinya tujuan dari proyek ini adalah kotak pasir otomatis dan menghindari neraka ketergantungan.

Dengan kata lain, ia menggunakan struktur paket Cabal yang sama, hanya menyediakan front-end yang berbeda untuk mengelola hal ini. (Kupikir!)

MathematicalOrchid
sumber
Selain itu cabal, kode sumber mereka tampaknya juga menggunakan docker. Meskipun saya belum tahu apakah mereka menggunakannya.
Sibi
@Sibi Ya, sepertinya Anda dapat secara opsional memasukkan barang ke Docker, dan itu dimaksudkan untuk berfungsi. Saya belum melihatnya lebih jauh ...
MathematicalOrchid