Saya melihat banyak teks, terutama teks pemrograman fungsional, mengklaim bahwa konsep CS tertentu "tidak menulis" . Contohnya adalah: kunci tidak menulis, monad tidak menulis.
Saya mengalami kesulitan melacak dengan tepat arti dari frasa ini. Ketika saya memikirkan komposisi, saya memikirkan komposisi fungsi atau agregasi objek (seperti dalam "komposisi yang disukai daripada warisan"), tetapi itu tampaknya tidak menjadi pengertian di mana orang menggunakannya di sini.
Dapatkah seseorang menjelaskan apa arti frasa ini ketika digunakan dalam ekspresi seperti dua contoh di atas (yaitu, kunci dan monad)?
Jawaban:
Ketika orang mengatakan "X tidak menulis", apa yang mereka maksud dengan "menulis" benar-benar hanya berarti "disatukan", dan apa dan bagaimana Anda menyatukannya bisa sangat berbeda, tergantung pada apa sebenarnya "X" itu.
Juga, ketika mereka mengatakan "tidak menulis", mereka dapat berarti beberapa hal yang sedikit berbeda:
Contoh untuk # 1 adalah parser dengan scanner / lexers. Anda mungkin mendengar ungkapan "scanner / lexers don't compose". Itu sebenarnya tidak benar. Apa yang mereka maksudkan adalah "parser yang menggunakan tahap lexing terpisah jangan menulis".
Mengapa Anda ingin membuat parser? Nah, bayangkan Anda adalah vendor IDE seperti JetBrains, Eclipse Foundation, Microsoft, atau Embarcadero, dan Anda ingin membangun IDE untuk kerangka kerja web. Dalam pengembangan web biasa, kami sering mencampur bahasa. Anda memiliki file HTML dengan
<script>
elemen yang mengandung ECMAScript dan<style>
elemen yang mengandung CSS. Anda memiliki file template yang berisi HTML, beberapa bahasa pemrograman, dan beberapa metasyntax bahasa template. Anda tidak ingin menulis highlight sintaks yang berbeda untuk "Python", "Python yang disematkan dalam templat", "CSS", "CSS dalam HTML", "ECMASCript", "ECMAScript di dalam HTML", "HTML", "HTML di dalam sebuah template ", dan seterusnya dan seterusnya. Anda ingin menulis penyorot sintaksis untuk Python, satu untuk HTML, satu untuk bahasa templat, dan kemudian menyusun ketiganya menjadi penyorot sintaksis untuk file templat.Namun, lexer mem-parsing seluruh file menjadi aliran token, yang hanya masuk akal untuk satu bahasa itu. Pengurai untuk bahasa lain tidak dapat bekerja dengan token yang dilewati oleh lexer. Sebagai contoh, parser Python biasanya ditulis sedemikian rupa sehingga lexer melacak lekukan dan menyuntikkan token
INDENT
dan palsuDEDENT
ke dalam aliran token, sehingga memungkinkan parser untuk bebas konteks meskipun sintaksis Python sebenarnya tidak. Namun HTML lexer akan sepenuhnya mengabaikan spasi putih, karena tidak memiliki arti dalam HTML.Namun, pengurai tanpa pemindai, yang hanya membaca karakter, dapat meneruskan aliran karakter ke pengurai yang berbeda, yang kemudian dapat mengembalikannya, sehingga membuatnya lebih mudah untuk dikomposisi.
Contoh untuk # 2 adalah string dengan query SQL di dalamnya. Anda dapat memiliki dua string, yang masing-masing memiliki kueri SQL yang benar secara sintaksis di dalamnya, tetapi jika Anda menggabungkan dua string, hasilnya mungkin bukan query SQL yang benar secara sintaksis. Itulah mengapa kita memiliki pertanyaan algebras seperti
ARel
, yang melakukan penulisan.Kunci adalah contoh dari # 3. Jika Anda memiliki dua program dengan kunci, dan Anda menggabungkannya menjadi satu program, Anda masih memiliki program dengan kunci, tetapi bahkan jika dua program asli sepenuhnya benar, bebas dari kebuntuan dan balapan, program yang dihasilkan tidak harus memiliki ini milik. Penggunaan kunci yang benar adalah properti global dari seluruh program, dan properti yang tidak dipertahankan ketika Anda menyusun program. Hal ini berbeda dari, misalnya, transaksi, yang melakukan penulisan. Suatu program yang menggunakan transaksi dengan benar dapat disusun dengan program lain semacam itu dan akan menghasilkan program gabungan yang menggunakan transaksi dengan benar.
sumber
Kompabilitas berarti bahwa Anda dapat dengan mudah dan andal menggabungkan komponen program bersama untuk menghasilkan komponen yang lebih besar dan fungsionalitas yang lebih kompleks.
Beberapa hal yang membantu membuat komponen lebih kompos:
Idempotensi. Fungsi idempoten akan selalu menghasilkan output atau efek samping yang sama, jika dipanggil beberapa kali dengan nilai parameter yang sama. Ini meningkatkan kemampuan menyusun karena hasil panggilan fungsi dapat diprediksi.
Transparansi Referensial. Ekspresi transparan-referensi akan selalu mengevaluasi hasil yang sama. Ini meningkatkan kemampuan menyusun dengan memungkinkan ekspresi identik untuk saling menggantikan satu sama lain, dan dengan memungkinkan ekspresi dihitung secara independen satu sama lain (yaitu pada utas yang berbeda) tanpa menggunakan kunci.
Kekekalan. Keadaan objek yang tidak dapat diubah tidak dapat diubah setelah dibuat. Ini meningkatkan kemampuan menyusun karena Anda dapat mengandalkan nilai objek yang stabil, tanpa khawatir jika beberapa fungsi atau objek di suatu tempat telah mengubah keadaan objek setelah dibuat.
Kemurnian. Fungsi murni tidak memiliki efek samping. Mereka hanya memiliki input dan output, yang membuatnya lebih mudah dikomposisikan karena Anda dapat memasukkan output dari satu fungsi ke input fungsi lain tanpa khawatir apakah sesuatu di luar fungsi telah berubah atau tidak.
Kunci tidak disusun karena merupakan elemen luar yang harus Anda andalkan ketika menggabungkan dua operasi bersama yang berbagi beberapa keadaan, dan untuk semua alasan yang ada hubungannya dengan kompleksitas yang melekat dalam penggunaan kunci.
Ungkapan "monad jangan menulis" tidak masuk akal bagi saya. Inti dari monad adalah untuk mengambil sesuatu yang stateful seperti input keyboard atau output layar, dan mengubahnya menjadi lebih murni, bentuk matematis yang, pada kenyataannya, lebih mudah digubah.
sumber
IO
jenis yang menangkap "tindakan negara" seperti input keyboard. Nilai-nilai dariIO
tipe memang, memang, menyusun, tapi itu adalah keseluruhan tipeIO
yang merupakan monad. Tipe ini tidak dikomposisi dengan tipe lain yang merupakan monad seperti, katakanlah, tipe daftar. Artinya, kita tidak bisa secara sistematis menghasilkan tipeIO . List
yang berperilaku seperti keduanyaIO
danList
secara bersamaan. Apakah itu masuk akal? Saya tidak yakin saya menjelaskannya dengan baik.