STDOUT dan ketidakmurniannya


10

Saya telah membaca banyak buku dan artikel tentang pemrograman fungsional dan masih malu karena tidak dapat memahami dengan pasti beberapa konsep yang sangat mendasar.

Salah satu ide utama pemrograman fungsional adalah input yang sama harus selalu menghasilkan output yang sama. Oleh karena itu, katakanlah, query database atau menulis file tidak dapat dilakukan dengan gaya fungsional murni menurut definisi. Itu misalnya, adalah salah satu alasan kita membutuhkan monad.

Pertanyaannya adalah - mengapa kita menganggap output STDOUT sebagai sesuatu yang tidak murni? Ya, pembuat file apa pun berisiko - kami tidak pernah dapat memastikan bahwa data akan selalu ditulis. Tapi bagaimana dengan STDOUT? Mengapa kita harus menganggapnya sebagai sesuatu yang tidak dapat diandalkan? Apakah evaluasi itu sendiri tidak dapat diandalkan? Maksud saya, kita selalu dapat menarik pelatuk dan dengan demikian, mengganggu perhitungan.

Jawaban:


6

Oleh karena itu, katakanlah, query database atau menulis file tidak dapat dilakukan dengan gaya fungsional murni menurut definisi. Itu misalnya, adalah salah satu alasan kita membutuhkan monad.

Tidak ada yang "membutuhkan" monad, itu hanya satu cara untuk menggambarkan berbagai hal. Bahkan, itu mungkin bukan cara terbaik. Beberapa bentuk efek pengetikan , tipe keunikan , atau sistem yang didasarkan pada logika linier penuh tampak lebih persuasif dalam teori tetapi semuanya lebih radikal dari sistem tipe yang terkenal dan lebih rumit untuk diekspresikan. IO monadik seperti yang ditemukan di Haskell adalah kompromi antara kegunaan dan kesederhanaan, karena pada dasarnya memodelkan pemrograman yang sangat penting dengan cara yang hidup berdampingan dengan mudah dengan sistem tipe gaya ML yang sudah digunakan dalam bahasa.

Pertanyaannya adalah - mengapa kita menganggap output STDOUT sebagai sesuatu yang tidak murni? Ya, pembuat file apa pun berisiko - kami tidak pernah dapat memastikan bahwa data akan selalu ditulis. Tapi bagaimana dengan STDOUT? Mengapa kita harus menganggapnya sebagai sesuatu yang tidak dapat diandalkan? Apakah evaluasi itu sendiri tidak dapat diandalkan? Maksud saya, kita selalu dapat menarik pelatuk dan dengan demikian, mengganggu perhitungan.

Tidak, dan kami tidak. Input ke, dan output dari, program secara keseluruhan dapat dengan mudah dianggap sebagai argumen dan hasil dari memperlakukan seluruh program sebagai satu fungsi murni yang besar. Selama itu mencetak hal yang sama ke stdout jika Anda memberinya hal yang sama dari stdin, itu masih fungsi murni. Bahkan, sebelum memperkenalkan IO monadik, Haskell menggunakan sistem I / O berbasis aliran yang menggunakan aliran malas murni untuk input dan output. Itu menjatuhkannya karena itu tampaknya menyakitkan untuk digunakan, yang mungkin memberi Anda beberapa ide mengapa Anda belum pernah mendengar hal seperti ini. :]

Untuk menjelaskan maksudnya dengan cara yang lebih konyol, pertimbangkan bahasa esoteris minimalis, Lazy K :

Lazy K adalah bahasa pemrograman fungsional yang dikumpulkan secara sampah dan transparan, dengan sistem I / O berbasis aliran yang sederhana.

Yang membedakan Lazy K dari bahasa lain adalah hampir tidak adanya fitur lainnya. Sebagai contoh, ia tidak menawarkan sistem tipe polimorfik Hindley-Milner yang terintegrasi. Itu tidak dikirim dengan perpustakaan standar yang luas dengan dukungan untuk pemrograman GUI platform-independen dan binding ke bahasa lain. Pustaka semacam itu tidak dapat ditulis karena, antara lain, Lazy K tidak menyediakan cara untuk mendefinisikan atau merujuk ke fungsi apa pun selain built-in. Ketidakmampuan ini dilengkapi dengan kurangnya dukungan untuk angka, string, atau tipe data lainnya. Namun demikian, Lazy K adalah Turing-complete

(...)

Program-program Lazy K hidup dalam ranah Platonis abadi yang sama dengan fungsi matematika, apa yang disebut halaman Unlambda "ranah yang diberkati dari kalkulus lambda murni yang tidak diketik." Sama seperti pengumpulan sampah menyembunyikan proses manajemen memori dari programmer, sehingga transparansi referensial menyembunyikan proses evaluasi. Fakta bahwa beberapa perhitungan diperlukan untuk melihat gambar set Mandelbrot, atau untuk "menjalankan" program Lazy K, adalah detail implementasi. Itulah esensi pemrograman fungsional.

(...)

Bagaimana menangani input dan output dalam bahasa tanpa efek samping? Dalam arti tertentu, input dan output bukanlah efek samping; mereka, jadi untuk berbicara, efek depan dan belakang. Demikian juga di Lazy K, di mana program hanya diperlakukan sebagai fungsi dari ruang input yang mungkin ke ruang output yang mungkin.

Saya ragu Anda akan menemukan bahasa yang lebih murni fungsional dari itu!


Perlu diingat, bahwa hal-hal di atas hanya berlaku pada dasarnya mengambil input dan output dari fungsi murni dan menghubungkannya ke stdin / stdout "eksternal" dengan cara tertentu. Ada perbedaan besar antara itu dan memiliki akses ke sistem I / O primitif tingkat nyata. Detail implementasi dari membaca dan menulis ke aliran dapat bocor pengotor kecuali jika dienkapsulasi dengan cermat.

Saya berharap ini adalah alasan utama Anda tidak dapat melakukan ini secara langsung di Haskell - kasing yang masuk akal tipis dibandingkan dengan menggunakan mono IO, dan untuk yang terakhir ada banyak manfaat untuk memiliki akses ke hal yang nyata. Saya percaya itu sebabnya, misalnya, argumen baris perintah untuk program tidak hanya diteruskan sebagai argumen main, meskipun tampaknya secara intuitif memang seharusnya demikian.

Anda dapat memulihkan versi minimal sesuatu seperti ini di program tertentu, meskipun - hanya menangkap argumen sebagai nilai-nilai murni dan kemudian menggunakan yang interactfungsi untuk sisa program anda.


Pak, saya harus akui, saya menikmati jawaban Anda di tumpukan mana pun. Anda pasti harus menulis buku Haskell dan saya TIDAK bercanda.
shabunc

@shabunc: Saya kadang-kadang bertanya-tanya seberapa dekat jumlah total jawaban saya di SO dengan menjadi ukuran buku sudah ...
CA McCann

Bisakah Anda memberikan contoh sistem berdasarkan logika linear penuh? Itu tampak menarik, jika ada.
konfigurator

@configurator: Perhatikan bagaimana saya menautkan ke bahasa tertentu untuk yang lain, tetapi halaman wikipedia untuk logika linier? Sayangnya, jika saya punya contoh, saya akan memberikannya. : [Yang saya dengar hanyalah prototipe parsial dan sistem eksperimental dari penelitian CS. Jika Anda ingin menggali lebih dalam tentang itu, berikut adalah beberapa bahan yang relatif mudah didekati pada sistem tipe linear yang mungkin bisa Anda mulai.
CA McCann

3

Sementara kemurnian dalam program fungsional adalah tujuan yang layak, kenyataannya adalah bahwa setiap program yang tidak sepele, berguna akan memiliki beberapa pengotor (atau "efek samping"), karena alasan yang Anda sebutkan.

Program yang sepenuhnya murni, menurut definisi, adalah kotak hitam tertutup, dan pada dasarnya tidak menarik.

Bahasa fungsional Haskell menangani masalah ini dengan mengisolasi efek samping seperti output dalam monads . Monad mempertahankan gaya pemrograman murni fungsional, sambil tetap memungkinkan untuk menghasilkan output.


tentu kamu benar Tetapi saya mengerti mengapa kemurnian 100% adalah utopia. Saya hanya bertanya tentang STDOUT.
shabunc

1
STDOUT adalah efek samping, sama seperti yang lain. Secara internal, monad akan melakukan pengecekan kesalahan yang mungkin diperlukan.
Robert Harvey

ya, IS IS tentang pertanyaan ini - mengapa itu dianggap sebagai efek samping seperti yang lain?
shabunc

2
Apa pun yang mengubah dunia luar dianggap sebagai efek samping.
Robert Harvey

1

Menulis ke STDOUT dapat gagal jika Anda tidak terhubung ke perangkat terminal, atau jika Anda (karena alasan tertentu) menutup file-deskriptor untuk itu.

Juga, STDOUT tidak selalu "layar konsol". Terkadang disalurkan ke program lain. Terkadang pipa rusak.


0

Ini membantu jika Anda berpikir tentang kemurnian dalam istilah "Mengubah keadaan dunia luar". Itu bisa termasuk menulis ke konsol, mencatat file, mengeluarkan CD atau "Meluncurkan Rudal".

Ini juga bisa menjadi masalah dalam hal eksekusi bersamaan. Jika Anda tahu suatu fungsi tidak memiliki efek samping, Anda dapat dengan mudah mengatur konkurensi karena Anda dapat membuktikan bahwa tidak ada kondisi balapan atau sejenisnya.


Mengubah keadaan dunia luar atau tergantung pada keadaan dunia luar. Lihat pertanyaan ini untuk diskusi lebih lanjut di sepanjang baris ini.
MatrixFrog
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.