Menggunakan sistem tipe "kuat" di dunia nyata, katakanlah, untuk aplikasi web skala besar?

29

Saya tahu ini adalah pertanyaan yang sangat luas, ambigu, dan mungkin filosofis. Sampai batas tertentu, kata kunci yang paling penting dalam pertanyaan - sistem tipe "kuat" - itu sendiri, tidak terdefinisi dengan baik . Jadi, izinkan saya mencoba menjelaskan apa yang saya maksud.

Konteks keseluruhan untuk pertanyaan

Kami telah membangun aplikasi web berskala sangat besar di Ruby on Rails dan kami umumnya senang dengan tumpukan kami. Ketika kami mau, kami dapat mengirimkan barang dengan sangat cepat - sesuatu yang bekerja untuk 90% kasus "bisnis", tanpa terlalu mengkhawatirkan sekitar 10% kasus tepi. Di sisi lain, dengan bantuan tinjauan kode & cakupan uji, kami bisa lambat & disengaja dan memastikan kami mencakup semua pangkalan - lagi, hanya dalam situasi yang layak mendapatkan pengawasan & keamanan yang lebih dekat.

Namun, seiring pertumbuhan tim, saya mulai merasa tidak nyaman dengan kurangnya "jaring pengaman" yang dimasukkan ke tumpukan kami.

Kami baru-baru ini mulai melakukan beberapa pengembangan Android asli di Jawa. Dan saya (dengan senang hati) diingatkan akan keamanan yang diberikan oleh bahasa yang dikompilasi / statis / diketik dengan sangat kuat.

  • Variabel salah ejaan, tipe data yang salah, pemanggilan fungsi yang salah, dan sejumlah kesalahan sepele ditangkap oleh IDE Anda sendiri. Semua karena IDE dapat menghubungkan ke kompiler dan memverifikasi aspek-aspek tertentu dari program "kebenaran".
  • Perlu mengubah tanda tangan fungsi? Mudah. Compiler + IDE dapat membantu Anda melihat SEMUA situs panggilan.
  • Perlu memastikan bahwa pengecualian tertentu selalu ditangani? Pengecualian yang diperiksa untuk penyelamatan Anda.

Sekarang, sementara fitur keamanan ini memiliki kelebihan, saya juga menyadari kelemahan mereka. Terlebih lagi, di dunia "boilerplate heavy" Java. Oleh karena itu, alih-alih Jawa, saya sudah mulai melihat banyak bahasa modern, "sangat diketik" yang sudah mulai digunakan orang pada hari ini. Sebagai contoh: Scala, Rust, Haskell, dll. Yang paling menarik minat saya adalah kekuatan sistem tipenya dan pemeriksaan statis / kompilasi waktu.

Sekarang, pertanyaannya

Bagaimana cara menggunakan sistem tipe kuat ini dan fitur statis / waktu kompilasi dalam aplikasi yang lebih besar?

Sebagai contoh, bagaimana saya bisa melangkah keluar dari jenis pengantar standar "hello world" untuk fitur-fitur canggih ini? Yang menggunakan sistem tipe kaya untuk memodelkan masalah bisnis-domain? Apakah sistem tipe membantu, atau menghalangi, ketika Anda berada di zona 30.000 LOC +? Apa yang terjadi pada jaring pengaman yang disediakan oleh sistem tipe ini (dan pemeriksaan waktu kompilasi) ketika sistem Anda berinteraksi dengan dunia luar yang diketik dengan lemah, misalnya. melalui JSON atau XML API, berbagai penyimpanan data, input pengguna, dll.

Saurabh Nanda
sumber
12
Ini di luar topik karena tidak ada jawaban nyata. Pertanyaan ini dimaksudkan untuk memancing diskusi yang beralasan ("Saya suka / tidak suka tipe statis karena ..."), bukan penjelasan faktual . Saran saya adalah untuk memilih salah satu bagian yang lebih spesifik dari pertanyaan Anda seperti "Apa yang terjadi pada jaring pengaman yang disediakan oleh sistem tipe ini ketika sistem Anda berinteraksi dengan dunia luar yang diketik dengan lemah?" dan tulis ulang pertanyaannya tentang itu. Anda akan mendapatkan jawaban yang pasti yang akan bermanfaat bagi pembaca masa depan dengan cara itu.
Benjamin Hodgson
5
Rekomendasi sumber daya juga di luar topik di sini (karena jawaban seperti itu kedaluwarsa dengan cepat dan kami benar-benar tidak lebih baik daripada Google dalam hal itu). Seperti yang dikatakan Benjamin, ada beberapa pertanyaan yang dapat dijawab terkubur di pos Anda, tetapi seluruh pos dalam keadaan saat ini pada dasarnya meminta orang untuk menggambarkan pengalaman mereka menggunakan bahasa ini, yang jauh lebih cocok untuk Quora atau Reddit daripada StackExchange situs Saya tidak downvoting, karena pertanyaan ini ditanyakan dengan baik, tapi itu bukan pertanyaan StackExchange.
Ixrec
4
Sistem tipe adalah alat, dan seperti alat lainnya, kemanjurannya sebagian besar tidak tergantung pada alat itu sendiri tetapi pada pengguna. Anda dapat memanfaatkan sistem tipe bahasa seperti Haskell untuk menyandikan invarian tentang logika bisnis Anda pada level type dan meminta invarian tersebut diperiksa oleh mesin (kompiler) pada waktu kompiler, tetapi untuk melakukan ini Anda perlu memahami semantik dari sistem tipe dan pengecekan tipe. Pertanyaan yang tepat bukanlah "apakah ini alat yang bagus untuk hal-hal web", tetapi "ini adalah beberapa masalah spesifik yang saya hadapi; bagaimana sistem tipe yang kuat dapat digunakan untuk mengatasinya?"
user2407038
5
Sebagian besar hal yang Anda gambarkan tidak ada hubungannya dengan sistem tipe. Mereka murni fitur IDE. Dengan pengecualian (tidak ada permainan kata-kata) dari pengecualian yang diperiksa, semua fitur yang Anda sebutkan telah ada di Smalltalk IDEs jauh sebelum mereka muncul dalam IDE untuk bahasa yang diketik secara statis. Bahkan, salah satu IDE Java yang paling banyak digunakan sebenarnya dimulai sebagai Smalltalk IDE yang dimodifikasi (IBM VisualAge Smalltalk, yang dimodifikasi untuk memahami kode Java tetapi masih ditulis dalam Smalltalk dan dirilis sebagai VisualAge Java, yang kemudian diangkut ke Jawa dan dirilis sebagai ...
Jörg W Mittag
4
... VisualAge Java Micro Edition, yang kemudian dipecah menjadi komponen yang dapat digunakan kembali dan dirilis sebagai Open Source dengan nama Eclipse). Agak ironis dalam konteks pertanyaan ini, justru karena sifat dinamis dari sistem Smalltalk bahwa Smalltalk IDE sangat kuat. Refactoring Otomatis ditemukan dan pertama kali diterapkan di Smalltalk, misalnya. Menurut logika Anda, Haskell harus memiliki IDE terbaik karena memiliki sistem tipe statis terkuat, terketat dari semua bahasa yang Anda sebutkan. Tapi ternyata tidak. Anda juga menyebutkan "menghubungkan ke kompiler". Ini punya ...
Jörg W Mittag

Jawaban:

34

Saya akan memberikan jawaban singkat karena kurangnya waktu saya saat ini, tetapi saya sedang mengerjakan dua proyek besar (> 100.000 LOC di Haskell) - flowbox.io dan luna-lang.org. Kami menggunakan Haskell untuk semua bagian, termasuk backend, kompiler dari bahasa pemrograman kami dan bahkan GUI berbasis webGL. Saya harus mengakui bahwa sistem tipe yang kuat dan mesin seperti "tipe dependen" dapat memandu Anda dan menyelamatkan Anda dari beban dan kerumitan yang diketahui dari bahasa lain. Kami menggunakan tipe yang sangat luas dan segala sesuatu yang dapat diperiksa dalam waktu kompilasi, dilakukan demikian. Faktanya, selama 3 tahun terakhir pengembangan, kami tidak pernah menemukan kesalahan runtime atau stack overflow (dan ini adalah sesuatu yang sangat luar biasa). Satu-satunya kesalahan adalah kesalahan logika jelas yang dibuat oleh programmer. Banyak orang mengatakan, bahwa jika sesuatu dikompilasi di Haskell, itu hanya berfungsi dan Anda harus cukup yakin itu tidak akan meledak di wajah Anda suatu hari nanti.

Menjawab bagian pertama dari pertanyaan: Anda dapat mempelajari tentang fitur-fitur sistem tipe kuat ini membaca beberapa blog yang hebat, seperti:

Faktanya, ada banyak blog bagus lainnya di luar sana (seperti planet Haskell ). Bagaimanapun, metode terbaik untuk benar-benar memahami sistem tipe canggih adalah mengembangkan perpustakaan open source yang bermanfaat. Kami (di Flowbox & Pesanan Byte Baru) merilis banyak perpustakaan (Anda dapat menemukannya di Hackage), jadi jika Anda tidak tahu apa yang harus dikembangkan, Anda selalu dapat terlibat dalam proyek-proyek kami - cukup kirim email kepada saya setiap kali Anda inginkan (email tersedia di luna-lang.org ).

danilo2
sumber
4
"Banyak orang mengatakan, bahwa jika sesuatu dikompilasi di Haskell, itu hanya berfungsi dan Anda harus cukup yakin itu tidak akan meledak di wajah Anda suatu hari nanti.": Saya hanya menggunakan Haskell untuk proyek-proyek kecil (walaupun tidak sepele) , tapi saya bisa mengkonfirmasi ini: Setelah kompiler Haskell puas saya jarang menemukan bug yang tersisa.
Giorgio
1
Saya mungkin salah satu dari "Haskell" yang paling membenci tipe (jadi saya menulis Haskell versi saya sendiri tanpa tipe ) - tapi untuk alasan yang berbeda, kebanyakan orang melakukannya. Ketika datang ke rekayasa perangkat lunak, saya juga memiliki perasaan bahwa, ketika GHC senang, program Anda hanya berfungsi. Sistem tipe Haskell seperti adalah alat utama tidak hanya untuk mendeteksi kesalahan manusiawi dalam pemrograman, tetapi untuk menjaga basis kode besar di bawah kendali Anda. (Saya selalu ingat pembenaran Giovanni untuk baju
besi
Blog Gabriel Gonzales adalah yang terbaik untuk memulai.
sam boosalis
@ danilo2 Telah mengirim email ke kontak @ alamat di situs web perusahaan Anda. Meminta Anda untuk merespons. Terima kasih!
Saurabh Nanda
@SaurabhNanda: Saya memeriksa kotak masuk kami dan saya tidak melihat pesan apa pun dari Anda. Sudahkah Anda mengirimnya ke kontak <at> luna-lang.org? Silakan hubungi saya langsung menulis ke wojciech saya <dot> danilo <at> gmail <dot> com dan kami akan menyelidiki apa penyebab masalah ini :)
danilo2
17

Yah, mengetik lemah vs kuat cukup jelas. Lebih jauh, karena yang paling dekat dengan penggunaan umum 'pengetikan kuat' adalah untuk merujuk hal-hal yang membuatnya sulit untuk mengetik, yang tidak meninggalkan apa pun untuk menggambarkan sistem tipe yang lebih kuat. Ini seperti mengatakan jika Anda dapat membawa kurang dari 30 pon Anda lemah, dan semua orang yang dapat mengangkat lebih banyak berada dalam kategori 'kuat' yang sama - perbedaan yang menyesatkan.

Jadi saya lebih suka definisi:

  • Sistem yang diketik dengan lemah menggunakan tipe untuk mencegah Anda melakukan hal-hal tertentu (seperti kesalahan)
  • Sistem yang diketik dengan kuat menggunakan tipe untuk melakukan sesuatu untuk Anda

Apa yang saya maksudkan dengan melakukan sesuatu untuk Anda? Nah, mari kita periksa menulis API konversi gambar dalam kerangka Servant (di Haskell, tetapi Anda tidak benar-benar perlu mengetahuinya untuk mengikuti, Anda akan melihat ...)

{-# LANGUAGE
    TypeOperators,
    DataKinds
    #-}

import Codec.Picture
import Data.Proxy
import Network.Wai.Handler.Warp (run)
import Servant
import Servant.JuicyPixels

main :: IO ()
main = run 8001 conversion

Ini mengatakan bahwa kami ingin beberapa modul termasuk paket Servant dan plugin JuicyPixels untuk Servant, dan bahwa titik masuk utama program adalah menjalankan fungsi 'konversi' pada port 8001 sebagai server menggunakan backend Warp. Abaikan sedikit bahasa.

conversion :: Application
conversion = serve (Proxy :: Proxy ConversionApi) handler

Ini mengatakan bahwa fungsi konversi adalah server di mana API harus cocok dengan tipe 'ConversionApi' dan permintaan ditangani oleh fungsi handler

type ConversionApi
     = ReqBody '[BMP, GIF, JPEG 50, PNG, TIFF, RADIANCE] DynamicImage
    :> Post '[BMP, GIF, JPEG 50, PNG, TIFF, RADIANCE] DynamicImage

Ini menentukan ConvesionApijenisnya. Dikatakan bahwa kita harus menerima jenis konten yang masuk yang ditentukan oleh daftar '[BMP, GIF, JPEG 50, PNG, TIFF, RADIANCE], dan menanganinya sebagai DynamicImage, dan kita harus mengembalikan DynamicImage yang dikonversi ke dalam rentang konten yang sama. jenis. Jangan khawatir tentang apa:> artinya, anggap saja itu sebagai sihir bahagia untuk saat ini.

Jadi, mengingat definisi yang saya sukai, sistem yang diketik dengan lemah sekarang dapat memastikan hal-hal seperti:

  • Anda tidak mengembalikan jenis konten keluar yang salah
  • Anda tidak menguraikan permintaan masuk sebagai jenis konten yang salah
  • Jika server kami lebih rumit, itu akan mencegah kami membuat URI yang salah bentuk, tetapi kami sebenarnya tidak mengembalikan halaman HTML mana pun untuk memuat tautan (dan tipenya memastikan bahwa kami tidak bisa!)
  • Sistem pengetikan yang sangat ambisius dan lemah bahkan mungkin memeriksa untuk memastikan bahwa kami menangani semua jenis konten yang masuk dan keluar secara menyeluruh, memungkinkan tipe itu juga bertindak sebagai dokumen spesifikasi, bukan hanya sebagai kendala.

Semua tujuan yang tinggi, tetapi sebenarnya tidak cukup untuk memenuhi syarat sebagai sistem yang diketik dengan kuat, mengingat definisi di atas. Dan sekarang kita harus sampai pada bagian yang sulit dari penulisan kode yang mengikuti spesifikasi ini. Dalam sistem tipe yang sangat kuat , kami menulis:

handler = return

Dan kemudian kita selesai. Itu dia, tidak ada lagi kode untuk ditulis . Ini adalah server web yang sepenuhnya operasional (modulo semua kesalahan ketik yang saya lewatkan). Tipe telah memberitahu kompiler segala yang diperlukan untuk membuat server web kami dari tipe dan paket (modul secara teknis) yang kami definisikan dan impor.

Jadi, bagaimana Anda belajar melakukan ini pada skala aplikasi utama? Yah, itu benar-benar tidak jauh berbeda dari menggunakannya dalam aplikasi skala kecil. Jenis yang absolut tidak peduli berapa banyak kode yang ditulis terkait dengan mereka.

Inspeksi tipe run time adalah sesuatu yang Anda mungkin ingin hindari, karena itu mengukir sejumlah besar manfaat dan memungkinkan tipe untuk membuat proyek Anda lebih rumit untuk dikerjakan, daripada memiliki tipe yang menyederhanakan hal-hal.

Karena itu, sebagian besar hanya soal praktik memodelkan hal-hal dengan tipe. Dua cara utama untuk memodelkan sesuatu (atau membangun sesuatu secara umum) adalah dari atas ke bawah dan dari atas ke bawah. Top down dimulai dengan tingkat operasi tertinggi, dan ketika Anda membangun model Anda memiliki bagian-bagian di mana Anda menunda pemodelan sampai nanti. Pemodelan bottom-up berarti Anda memulai dengan operasi dasar, sama seperti Anda memulai dengan fungsi-fungsi dasar, kemudian membangun model yang lebih besar dan lebih besar sampai Anda sepenuhnya menangkap operasi proyek. Bottom up lebih konkret dan kemungkinan lebih cepat untuk dibangun, tetapi top-down mungkin lebih baik menginformasikan model tingkat bawah Anda tentang bagaimana mereka harus benar-benar berperilaku.

Jenis adalah bagaimana program berhubungan dengan matematika, secara harfiah, jadi tidak ada batas atas seberapa rumitnya mereka bisa, atau titik di mana Anda bisa 'selesai' belajar tentang matematika. Hampir semua sumber daya di luar program universitas tingkat tinggi semuanya didedikasikan untuk bagaimana jenis bekerja dalam beberapa bahasa tertentu, jadi Anda perlu memutuskan itu juga.

Yang terbaik yang bisa saya tawarkan, tipe dapat dikelompokkan seperti:

  • Ketik yang sangat lemah, hal-hal seperti JavaScript tempat [] + {} didefinisikan
  • Ketikan yang lemah seperti Python, di mana Anda tidak dapat melakukan [] + {}, tetapi itu tidak dicentang hingga Anda mencobanya
  • Ketikan yang lemah seperti C atau Java, di mana Anda tidak dapat melakukan [] + {}, tetapi itu diperiksa pada waktu kompilasi, namun Anda tidak memiliki fitur tipe yang lebih canggih
  • Mengangkangi batas antara mengetik dengan lemah dan sangat, seperti metaprogramming template C ++, dan kode Haskell yang lebih sederhana di mana tipe hanya properti penguat.
  • Sepenuhnya ke Sangat diketik, seperti program Haskell yang lebih rumit di mana jenis melakukan hal-hal, seperti yang ditunjukkan di atas
  • Yang diketik sangat kuat, seperti Agda atau Idris, di mana tipe dan nilai berinteraksi dan dapat saling membatasi. Ini sekuat sistem tipe dapatkan, dan pemrograman di dalamnya sama dengan menulis bukti matematika tentang apa yang program Anda lakukan. Catatan: pengkodean dalam Agda tidak secara harfiah menulis bukti matematis, tipe adalah teori matematika, dan fungsi dengan tipe tersebut adalah contoh konstruktif yang membuktikan teori-teori tersebut.

Secara umum, semakin jauh dalam daftar ini Anda pergi, semakin banyak jenis yang bisa lakukan untuk Anda, tetapi pada bagian paling bawah, Anda naik ke stratosfer dan udaranya semakin tipis - ekosistem paket jauh lebih kecil dan Anda ' Saya harus menulis lebih banyak hal sendiri vs telah menemukan perpustakaan yang relevan. Hambatan untuk masuk juga semakin tinggi saat Anda turun, karena Anda harus benar-benar memahami jenis sistem yang cukup untuk menulis program skala besar.

Steven Armstrong
sumber
Perhatikan bahwa Anda tidak perlu awalan daftar tingkat-jenis dengan tanda kutip jika ada lebih dari elemen dalam daftar. Apostrof hanya diperlukan untuk daftar level-level tipe 0 atau 1 elemen karena mereka ambigu (bisa merujuk pada konstruktor tipe daftar biasa)
Gabriel Gonzalez
1
Saya sadar, tetapi saya mendapat kesan bahwa tanda kutip itu hanya bentuk yang bagus untuk tipe data yang dipromosikan secara umum. EG yang Proxy :: Proxy Trueberfungsi, tetapi lebih baik untuk menuliskannya sebagai Proxy :: Proxy 'True.
Steven Armstrong
1
Tampaknya lebih baik untuk tidak menutup berbagai sumbu sesuai dengan sistem tipe mana yang dapat diklasifikasikan. Lambda cube Barendregt sudah termasuk tiga, dan selain itu sepanjang sumbu lemah-kuat Anda juga termasuk statis vs dinamis, dan parametrik vs polimorfisme ad hoc (yang terakhir adalah apa yang memungkinkan teknik pelayan untuk membuat jenis melakukan banyak pekerjaan ' ').
user2141650
1
Poin yang adil, tetapi jawabannya sudah sangat lama, dan Anda harus baik-baik saja dalam mempelajari teori tipe sebelum kubus lambda benar-benar mulai masuk akal. Selanjutnya, di luar ceruk yang sangat (dan karena saya sudah termasuk Haskell dan bahkan Agda, saya benar-benar sangat berarti ceruk) bahasa, Anda tidak benar-benar akan menemukan bahasa yang memiliki, misalnya, tipe tergantung tetapi tidak ada operator tipe .
Steven Armstrong
Bisakah Anda menjelaskan secara singkat '[xs]sintaks? Ini jelas bukan Char, tapi saya tidak melihat bagaimana TypeOperatorsatau DataKindsmengaktifkan sintaks alternatif. Apakah ini semacam quasiquoting?
wchargin
10

Saya baru saja mulai bekerja pada tim inti dari platform besar yang ditulis dalam Scala. Anda dapat melihat aplikasi open source yang sukses, seperti Scalatra, Play, atau Slick untuk melihat bagaimana mereka menangani beberapa pertanyaan Anda yang lebih terperinci tentang interaksi dengan format data dinamis.

Salah satu keuntungan besar yang kami temukan dari pengetikan kuat Scala adalah dalam pendidikan pengguna. Tim inti dapat membuat keputusan dan menegakkan keputusan-keputusan itu dalam sistem tipe, jadi ketika tim lain yang jauh kurang akrab dengan prinsip-prinsip desain harus berinteraksi dengan sistem, kompiler mengoreksi mereka, dan tim inti tidak terus-menerus memperbaiki hal-hal di tarik permintaan. Ini adalah keuntungan besar dalam sistem besar.

Tentu saja, tidak semua prinsip desain dapat diterapkan dalam sistem tipe, tetapi semakin kuat sistem tipe Anda, semakin banyak prinsip desain yang dapat Anda terapkan dalam kompiler.

Kami juga dapat membuat segalanya lebih mudah bagi pengguna. Seringkali bagi mereka, mereka hanya bekerja dengan koleksi reguler atau kelas kasus, dan kami mengonversinya ke JSON atau apa pun secara otomatis yang diperlukan untuk transportasi jaringan.

Pengetikan yang kuat juga membantu membedakan antara hal-hal seperti input yang tidak bersih dan sanitasi, yang dapat membantu keamanan.

Mengetik dengan kuat juga membantu tes Anda menjadi lebih fokus pada perilaku Anda yang sebenarnya , alih-alih membutuhkan banyak tes yang hanya menguji tipe Anda. Itu membuat pengujian jauh lebih menyenangkan, lebih fokus, dan karenanya lebih efektif.

Kerugian utama adalah tidak terbiasa dengan bahasa dan paradigma bahasa, dan itu dapat diperbaiki dengan waktu. Selain itu, kami telah menemukan upaya yang sepadan.

Karl Bielefeldt
sumber
8

Meskipun bukan jawaban langsung (karena saya belum bekerja di +30.000 basis kode LOC di haskell :( ..), saya mohon Anda untuk memeriksa https://www.fpcomplete.com/business/resources/case-studies / yang menampilkan banyak studi kasus haskell dalam pengaturan industri aktual.

Artikel bagus lainnya adalah IMVU, yang menggambarkan pengalaman mereka berubah menjadi haskell - http://engineering.imvu.com/2014/03/24/what-its-like-to-use-haskell/ .

Dari pengalaman pribadi dalam aplikasi yang lebih besar, sistem tipe sangat membantu Anda, terutama jika Anda mencoba untuk menyandikan sebanyak mungkin dalam jenis. Kekuatan sebenarnya benar-benar jelas ketika datang ke hal-hal refactoring - yang berarti pemeliharaan dan semacamnya menjadi tugas yang jauh lebih mengkhawatirkan.

Saya akan membuang beberapa tautan ke sumber daya yang saya rekomendasikan, karena Anda mengajukan cukup banyak pertanyaan sekaligus:

Sebagai komentar penutup, tentang berurusan dengan dunia luar dilakukan dalam beberapa cara. Ada perpustakaan untuk memastikan hal-hal di ujung Anda adalah tipe aman, seperti Aeson untuk JSON, Esqueleto untuk SQL dan banyak lagi.

Tehnix
sumber
1
terima kasih atas jawabannya, namun, studi kasus pada fpcomplete.com/business/resources/case-studies tidak lagi tersedia.
Saurabh Nanda
Sepertinya studi kasus dipindahkan ke fpcomplete.com/case-study
Steven Shaw
3

Apa yang saya lihat:

Saya telah mengerjakan beberapa aplikasi web Ruby besar (Rails), satu aplikasi web Haskell besar, dan beberapa yang lebih kecil. Dengan pengalaman itu saya harus mengatakan bahwa kehidupan yang bekerja pada aplikasi Haskell jauh lebih mudah daripada di Rails dalam hal seperti pemeliharaan dan kurva belajar yang lebih rendah. Saya berpendapat bahwa manfaat ini karena sistem tipe Haskell dan gaya pemrograman fungsional. Namun, tidak seperti banyak, saya percaya bahwa bagian "statis" dari sistem tipe hanya kenyamanan besar karena masih ada manfaat yang bisa didapat ketika menggunakan kontrak dinamis.

Apa yang saya yakini

Ada paket bagus yang disebut Kontrak Ruby yang berjalan bersama dalam menyediakan beberapa fitur utama yang saya rasa membantu proyek Haskell mencapai karakteristik perawatan yang lebih baik. Kontrak Ruby melakukan pemeriksaannya pada saat run-time sehingga yang terbaik adalah ketika dipasangkan dengan konvergen tes tinggi tetapi masih memberikan dokumentasi in-line dan ekspresi maksud dan makna yang sama seperti menggunakan anotasi jenis dalam bahasa seperti Haskell.

Anwser to Question

Untuk menjawab pertanyaan-pertanyaan yang diajukan di atas, ada banyak tempat di mana orang dapat terbiasa dengan Haskell dan bahasa lain dengan sistem tipe canggih. Namun, dan harus benar-benar jujur, sementara sumber-sumber dokumentasi ini sangat baik dalam hak mereka sendiri, mereka semua tampak agak underwhelming bila dibandingkan dengan kebanyakan dokumentasi dan saran praktis yang ditemukan dalam bahasa Ruby, Python, Jawa dan bahasa-bahasa lain semacam itu. Bagaimanapun, Real World Haskell semakin tua tetapi masih merupakan sumber yang bagus.

Kategori Teori

Jika Anda memilih Haskell, Anda akan menemukan banyak literatur yang membahas teori Kategori. Teori kategori IMHO berguna tetapi tidak perlu. Mengingat prevalensi dalam komunitas Haskell, mudah untuk mengacaukan pro dan kontra dari jenis dengan perasaan tentang kepraktisan teori Kategori. Sangat membantu untuk mengingat mereka adalah dua hal yang berbeda, yaitu untuk mengatakan bahwa implementasi dipandu oleh teori Kategori dapat dilakukan dalam bahasa yang diketik secara dinamis sama seperti statis (modulo manfaat yang disediakan oleh sistem tipe). Sistem tipe lanjutan pada umumnya tidak terikat pada teori Kategori dan teori Kategori tidak terikat pada sistem tipe.

Lebih lanjut tentang Jenis

Ketika Anda belajar lebih banyak tentang pemrograman dengan tipe dan teknik di dalamnya (yang terjadi cukup cepat karena menyenangkan), Anda akan ingin mengekspresikan lebih banyak dengan sistem tipe. Dalam hal ini saya akan melihat ke beberapa sumber daya berikut dan bergabung dengan saya dalam membuat vendor alat sadar bahwa kami ingin alat berkualitas industri dengan fitur-fitur ini hanya dikemas menjadi sesuatu yang memperlihatkan antarmuka yang mudah digunakan (seperti Kontrak Ruby):

Eric
sumber
2

Pertama, saya merasa seperti ada kebingungan dalam jawaban antara yang diketik dengan lemah versus diketik dengan kuat, dan statis versus diketik secara dinamis. Tautan OP yang disediakan jelas membuat perbedaan:

Sistem tipe kuat adalah sistem tipe yang memiliki batasan waktu kompilasi atau fitur run-time yang Anda anggap menarik.

Sistem tipe lemah adalah sistem tipe yang tidak memiliki batasan atau fitur.

Sebagai contoh, C, C ++ dan Java diketik secara statis karena variabel diketik pada waktu kompilasi. Namun, C dan C ++ dapat dianggap diketik dengan lemah karena bahasa memungkinkan untuk memotong pembatasan menggunakan void *pointer dan gips. Lebih banyak tentang topik ini.

Pada perbedaan ini, pengetikan yang kuat hanya bisa lebih baik. Semakin awal gagal, semakin baik.

Namun, pada penulisan program besar, saya tidak berpikir sistem tipe memainkan peran penting. Kernel Linux adalah sepuluh juta LOC yang ditulis dalam C dan assembly dan dianggap sebagai program yang sangat stabil, itu jauh dari 200 baris Java saya yang mungkin penuh dengan lubang keamanan. Demikian pula, meskipun "bahasa skrip" yang diketik secara dinamis menderita reputasi buruk ketika menulis program besar, kadang-kadang ada bukti bahwa itu tidak layak (seperti Python Django, lebih dari 70k LOC)

Menurut pendapat saya, ini semua tentang standar kualitas. Tanggung jawab untuk skalabilitas aplikasi besar seharusnya hanya dipegang oleh programmer dan arsitek dan keinginan mereka untuk membuat aplikasi bersih, diuji, didokumentasikan dengan baik dll.

Arthur Havlicek
sumber
-1

Di mana orang dapat membaca tentang bagaimana menggunakan sistem tipe yang kuat ini dan fitur statis / waktu kompilasi dalam aplikasi yang lebih besar?

dari jawaban sebelumnya https://www.fpcomplete.com/business/resources/case-studies/

Bagaimana cara seseorang bergerak di luar pengantar standar "halo dunia" ke fitur-fitur canggih ini?

itu benar-benar seperti bahasa lain untuk membangun kekuatan

Bagaimana cara menggunakan sistem tipe kaya untuk memodelkan masalah domain bisnis?

Dengan menggunakan Jenis Data Abstrak, atau lebih umum polimorfisme

Apakah sistem tipe membantu, atau menghalangi, ketika Anda berada di zona 30.000 LOC +?

Itu membantu sepanjang jalan. sistem tipe membantu Anda menulis kode karena memberi tahu Anda bentuk hasil yang ingin Anda miliki. Sebenarnya Agda menulis kode untuk kamu.

PS: jangan membuat kesalahan dengan memiliki sistem jenis dan harus menulis sendiri jenisnya, yang bodoh: komputer dapat melakukannya untuk Anda.

Apa yang terjadi pada jaring pengaman yang disediakan oleh sistem tipe ini (dan pemeriksaan waktu kompilasi) ketika sistem Anda berinteraksi dengan dunia luar yang diketik dengan lemah, misalnya. melalui JSON atau XML API, berbagai penyimpanan data, input pengguna, dll.

Ini bagus, karena mengetahui struktur nilai melalui tipe berarti komputer dapat menyimpulkan cara untuk menulis (de) serializer untuk Anda.

Jika Anda benar-benar ingin tahu tentang jenis dan abstraksi, pengantar terbaik adalah Pada Jenis Pemahaman, Abstraksi Data, dan Polimorfisme

Ini kertas, bukan studi kasus dengan gambar-gambar cantik, tapi mencerahkan

nicolas
sumber
-2

Sebagai seorang programmer. Net yang bekerja pada aplikasi web banyak saya melihat kedua sisi C # diketik dan Javascript yang belum diketik.

Saya tidak yakin saya telah melihat literatur tentang pertanyaan yang Anda ajukan. Dengan bahasa yang diketik Anda menerima semua hal ini begitu saja. Dengan yang belum diketik Anda melihat mendefinisikan jenis sebagai overhead yang tidak perlu.

Secara pribadi, saya tidak berpikir Anda dapat menyangkal bahwa bahasa yang diketik sangat menawarkan manfaat yang Anda gambarkan dengan biaya yang sangat rendah (dibandingkan dengan menulis tes unit yang setara). Berinteraksi dengan sistem yang diketik dengan lemah biasanya melibatkan tipe generik, seperti Array atau Kamus Objek, seperti DataReader, atau penggunaan kreatif string atau kelas dinamis baru. Intinya semuanya berfungsi, Anda hanya mendapatkan kesalahan runtime alih-alih waktu kompilasi.

Jika Anda ingin menulis program yang sangat singkat, mungkin mendefinisikan fungsi dalam beberapa baris untuk bekerja dengan aplikasi yang lebih besar, maka Anda tidak punya ruang untuk mendeklarasikan kelas. Tentunya ini adalah bahasa yang tidak diketik seperti JS yang ditempati?

Ewan
sumber
Apakah maksud Anda mengetik / tidak mengetik atau mengetik secara statis / diketik secara dinamis? JavaScript tidak diketik tetapi diketik secara dinamis.
Giorgio
2
Anda tidak perlu mendefinisikan tipe. bahasa apa pun yang layak akan menyimpulkan tipe untuk Anda: haskell, ocaml, sml, F # ...
nicolas
1
ketika Anda terbiasa dengan bahasa yang diketik dengan kuat, segala sesuatu yang lain tidak diketik, ketika saya mengatakan tentukan jenis yang saya maksud 'buat kelas' yakin Anda dapat menggunakan var atau apa pun, tetapi itu hanya trik kompiler
Ewan