Apakah ada teori hierarki pengecualian?

18

Saya akrab dengan selusin bahasa pemrograman yang memiliki pengecualian dalam beberapa cara, namun saya datang untuk menyaksikan dua kecenderungan "patologis".

  1. Tampaknya tidak ada pola umum atau hierarki pengecualian. Setiap bahasa pada dasarnya memutar versinya sendiri, dan jika pengecualian membuatnya menjadi standar, maka jenis-jenis pengecualian yang ditemukan dalam standar akan agak arbitrer (kebanyakan yang diterapkan saat membuat alat bahasa, seperti membaca kode sumber dari string atau pengecualian untuk memanggil debugger, atau yang terjadi ketika file tidak dapat ditemukan dll.)

  2. Pengecualian yang ditentukan oleh bahasa sangat jarang digunakan kembali oleh program pengguna. Biasanya akan ada satu atau dua pengecualian populer ("tidak diterapkan" misalnya). Padahal seringkali programmer akan membuat pengecualian sendiri. (Bandingkan ini dengan, misalnya, membuat tipe numerik baru atau tipe koleksi baru).

Ini tampak seperti kelalaian yang mengerikan bagi saya. Kenapa tidak ada yang tahu jenis kesalahan apa yang akan dibutuhkan dalam program pengguna? Saya berharap ada semacam hierarki yang bagus, mirip dengan tipe numerik, koleksi, sistem objek, dll.

Lebih buruk lagi, Goolge dan Wikipedia memberikan sedikit bantuan tentang masalah ini. Sejauh ini saya hanya menemukan makalah tentang pengecualian fungsional yang terbuka dalam sebuah bagian:

Makalah ini berpendapat bahwa pemrograman fungsional yang malas tidak hanya membuat mekanisme penanganan pengecualian bawaan tidak diperlukan, tetapi juga menyediakan alat yang kuat untuk mengembangkan dan mengubah program yang menggunakan pengecualian.

(Teori Fungsional Pengecualian, Mike Spivey, 1988)

Tapi saya pikir pengecualian itu baik. Saya tidak ingin mengubah program yang menggunakan pengecualian, sebaliknya, saya ingin membuat penggunaan pengecualian menjadi lebih kacau.

Pertanyaan:

Apakah ada teori pengecualian? Jika demikian, apa sebutannya? Apa, jika ada, batu penjuru yang berfungsi menguraikan dasar dari itu?

wvxvw
sumber
pengecualian adalah penemuan yang agak baru, mungkin kurang dari ~ 20 tahun, yang timbul dari "longjmp" C. mereka sebagian besar terhubung ke OOP. tampaknya penggunaan / teori / praktik terbaik yang ideal masih dalam evolusi. java memiliki salah satu model yang lebih rumit. ada banyak "antipatterns" yang berkaitan dengan pengecualian seperti yang Anda perhatikan. beberapa di antaranya terhubung dengan teori "komputasi yang toleran terhadap kesalahan" yang tampaknya juga masih sangat baru.
vzn
Anda dapat mempertimbangkan pengecualian sebagai subset dari teori kelanjutan. Lihat en.wikipedia.org/wiki/Continuation
jmite
@jmite Pengecualian dan lanjutan sangat berbeda. Pengecualian mengikat secara dinamis ke penangan mereka, sementara kelanjutan melakukannya secara statis. Secara umum, kelanjutan sendiri tidak dapat digunakan untuk menerapkan pengecualian, setidaknya dengan adanya tipe, lihat misalnya Pengecualian dan Kelanjutan Ketikan Tidak Dapat Makro-Ekspres Satu Sama Lain .
Martin Berger
"Pengecualian yang ditentukan oleh bahasa sangat jarang digunakan kembali oleh program pengguna." Ini sangat benar! Menentukan pengecualian khusus sangat jarang diperlukan. Misalnya python dan stdlibnya mendefinisikan sesuatu seperti 160 pengecualian. Kemungkinan pengecualian yang Anda pikirkan tidak didefinisikan di sana sangat kecil. Beberapa (sebagian besar?) Pengecualian ini tidak diketahui secara luas. Sebagai contoh LookupErrorakan baik-baik saja untuk setiap wadah kustom, tetapi saya banyak orang bahkan tidak tahu itu ada.
Bakuriu
1
@jmite Satu lagi pertemuan yang saya miliki dengan pengecualian sebelum topik ini dari buku Benjamin C. Pierce Jenis dan Bahasa Pemrograman. Di mana ia menyebutkan kesalahan dalam konteks mendefinisikan tipe fungsi. Yaitu dari sudut pandangnya, kesalahan hanyalah nilai-nilai lain yang dikembalikan dari fungsi (dan bersama-sama dengan argumen lain mereka membentuk tipe keseluruhan, jika saya diizinkan untuk mengatakannya).
wvxvw

Jawaban:

8

Ada banyak publikasi tentang pengecualian, dengan beberapa investigasi teoretis. Berikut adalah daftar yang tidak terstruktur dan jauh dari lengkap dengan beberapa contoh. Maaf, saat ini saya tidak punya waktu untuk jawaban yang lebih fokus.

  • B. Randell, Struktur Sistem untuk Toleransi Kesalahan Perangkat Lunak.
  • JB Goodenough. Penanganan pengecualian: Masalah dan notasi yang diusulkan.
  • JB Goodenough. Penanganan pengecualian terstruktur.
  • BG Ryder, ML Soffa, Pengaruh pada Desain Penanganan Pengecualian.
  • D. Teller, A. Spiwack, T. Varoquaux, Tangkap saya jika Anda dapat: Menuju manajemen kesalahan yang aman, hierarkis, ringan, polimorfik, dan efisien di OCaml.
  • X. Leroy, F. Pessaux, analisis berbasis tipe dari pengecualian yang tidak tertangkap.
  • R. Miller, A. Tripathi, Masalah dengan Penanganan Pengecualian dalam Sistem Berorientasi Objek.
  • S. Drew, KJ Gough, J. Ledermann, Menerapkan Penanganan Eksepsi Nol-Overhead.
  • B. Stroustrup, Keamanan Pengecualian: Konsep dan Teknik.
  • D. Malayeri, J. Aldrich, Spesifikasi Pengecualian Praktis.
  • H. Nakano, Formalisasi Konstruktif dari Mekanisme Tangkapan dan Lempar.
  • A. Nanevski, Kalkulus Modal untuk Penanganan Pengecualian.
  • P. de Groote, Kalkulus Sederhana Penanganan Pengecualian.
  • H. Thielecke, Tentang Pengecualian dan Kelanjutan dalam Kehadiran Negara.
  • JG Riecke, H. Thielecke, Pengecualian yang Diketik dan Lanjutan Tidak Dapat Makro-Ekspres Satu Sama Lain.
  • M. van Dooren, E. Steegmans, Menggabungkan Kuatnya Pengecualian yang Dicentang dengan Fleksibilitas Pengecualian yang Tidak Dicentang menggunakan Deklarasi Perkecualian Berlabuh.
  • JA Vaughan, Penafsiran logis dari pengecualian gaya Jawa.
  • S. Marlow, S. Peyton Jones, A. Moran, Pengecualian Asinkron dalam Haskell.
  • B. Jacobs, F. Piessens, Failboxes: Penanganan Pengecualian yang Terbukti Aman.
Martin Berger
sumber
Wow, terima kasih banyak! Akan memakan waktu beberapa bulan (jika tidak lebih) untuk kembali dengan jawaban positif :) Sekarang saya terpecah di antara beberapa buku yang tidak tahu harus mulai dari mana!
wvxvw
2
Banyak makalah ini tentang menerapkan atau memodelkan pengecualian dalam bahasa pemrograman, dan bukan bagaimana merancang hierarki pengecualian. Bisakah Anda memotong daftar ke kertas yang relevan?
Gilles 'SANGAT berhenti menjadi jahat'
@Gilles Pertanyaan aslinya agak tidak jelas. Saya rasa apa yang dianggap sebagai pengecualian yang sesuai sebagian besar tergantung pada aplikasi. Satu-satunya masalah teoritis nyata dengan pengecualian adalah pertukaran antara (1) menggabungkan modul yang tidak terkait melalui pengecualian (ini sebabnya tidak ada bahasa setelah Java memiliki spesifikasi pengecualian wajib), (2) memberikan pengguna modul beberapa indikasi jenis erros apa yang diharapkan , dan (3) bantuan kompiler dengan penanganan kesalahan. Sejauh yang saya bisa lihat, belum ada solusi yang meyakinkan untuk teka-teki ini.
Martin Berger
6

Saya tidak tahu apakah ada teori atau tidak, tetapi mungkin ada sains eksperimental pragmatis yang muncul.

Sumber terbaik yang dapat saya pikirkan adalah Bjarne Stroustrup, Desain dan Evolusi C ++, Addison-Wesley, 1994 . Jika saya ingat dengan benar (itu buku yang sangat bagus dan orang-orang terus meminjamnya dari saya dan tidak mengembalikannya, jadi saya tidak punya salinannya saat ini) ada bab tentang pengecualian. Komite C ++ di bawah Stroustrup membutuhkan banyak bukti empiris bahwa fitur yang diusulkan diperlukan sebelum mereka mau menambahkannya ke definisi bahasa. The Wikipedia Halaman tentang pengecualian memiliki kutipan berikut dari buku itu:

Pada pertemuan Palo Alto [standarisasi C ++] pada bulan November 1991, kami mendengar ringkasan yang cemerlang dari argumen untuk semantik terminasi yang didukung dengan pengalaman pribadi dan data dari Jim Mitchell (dari Sun, sebelumnya dari Xerox PARC). Jim telah menggunakan penanganan pengecualian dalam setengah lusin bahasa selama periode 20 tahun dan merupakan pendukung awal semantik kembalinya sebagai salah satu perancang dan pelaksana utama sistem Cedar / Mesa Xerox. Pesannya adalah penghentian lebih disukai daripada dilanjutkan; ini bukan masalah pendapat tetapi masalah pengalaman bertahun-tahun. Pengembalian memang menggoda, tetapi tidak valid. Dia mendukung pernyataan ini dengan pengalaman dari beberapa sistem operasi. Contoh kuncinya adalah Cedar / Mesa: Itu ditulis oleh orang-orang yang suka dan menggunakan kembalinya, tetapi setelah sepuluh tahun digunakan, hanya ada satu penggunaan resume yang tersisa di sistem setengah juta baris - dan itu adalah penyelidikan konteks. Karena pembukaan kembali sebenarnya tidak diperlukan untuk penyelidikan konteks seperti itu, mereka menghapusnya dan menemukan peningkatan kecepatan yang signifikan di bagian sistem itu. Dalam setiap kasus di mana pembukaan kembali telah digunakan - selama sepuluh tahun - menjadi masalah dan desain yang lebih tepat telah menggantinya. Pada dasarnya, setiap penggunaan pembukaan kembali telah mewakili kegagalan untuk menjaga tingkat abstraksi terpisah terpisah. Dalam setiap kasus di mana pembukaan kembali telah digunakan - selama sepuluh tahun - menjadi masalah dan desain yang lebih tepat telah menggantinya. Pada dasarnya, setiap penggunaan pembukaan kembali telah mewakili kegagalan untuk menjaga tingkat abstraksi terpisah terpisah. Dalam setiap kasus di mana pembukaan kembali telah digunakan - selama sepuluh tahun - menjadi masalah dan desain yang lebih tepat telah menggantinya. Pada dasarnya, setiap penggunaan pembukaan kembali telah mewakili kegagalan untuk menjaga tingkat abstraksi terpisah terpisah.

Dalam C ++, kemenangan sebenarnya adalah RAII , yang membuatnya lebih mudah untuk menangani alokasi sumber daya selama kesalahan. (Itu tidak menghilangkan kebutuhan untuk throwdan try- catch, tetapi itu berarti Anda tidak perlu finally.)

Saya pikir hal yang meyakinkan mereka bahwa mereka membutuhkan pengecualian adalah wadah generik: penulis wadah tidak tahu apa pun tentang jenis kesalahan yang mungkin perlu dikembalikan oleh benda yang terkandung (apalagi cara menanganinya), tetapi kode yang memasukkan benda-benda itu ke dalam wadah harus tahu sesuatu tentang apa antarmuka benda-benda itu. Tapi karena kita tidak tahu apa-apa tentang kesalahan apa yang bisa dilontarkan oleh objek yang terkandung, kita tidak bisa membakukan pada tipe pengecualian. (Kontrapositif: jika kita dapat membakukan jenis pengecualian maka kita tidak perlu pengecualian.)

Hal lain yang orang tampaknya telah pelajari selama bertahun-tahun adalah bahwa spesifikasi pengecualian sulit untuk dimasukkan ke dalam bahasa dengan benar. Lihat misalnya ini: http://www.gotw.ca/publications/mill22.htm , atau ini: http://www.gotw.ca/gotw/082.htm . (Dan itu bukan hanya C ++, programmer Java juga memiliki argumen panjang tentang pengalaman mereka dengan pengecualian diperiksa dan tidak dicentang .)

Sedikit tentang sejarah pengecualian. Makalah klasik adalah: John B. Goodenough: "Penanganan pengecualian: masalah dan notasi yang diusulkan," Komun. ACM 18 (12): 683-696, 1975. Tetapi pengecualian telah diketahui sebelumnya. Mesa memilikinya pada sekitar 1974, dan PL / saya mungkin juga memilikinya. Ada memiliki mekanisme pengecualian sebelum 1980. Saya percaya bahwa pengecualian C ++ paling dipengaruhi oleh pengalaman dengan bahasa pemrograman CLU Barbara Liskov dari sekitar 1976. Barbara Liskov: "Sejarah CLU," dalam Sejarah bahasa pemrograman --- II , Thomas J. Bergin, Jr. dan Richard G. Gibson, Jr (Eds.). hlm. 471-510, ACM, 1996 .

Logika Pengembaraan
sumber
Ini menarik dan saya harus meneliti lebih banyak untuk membalas lebih baik. Tetapi sejauh ini: Saya tahu ada keberatan yang sangat kuat untuk menggunakan pengecualian dalam C ++ (mungkin anekdot, tetapi konvensi pengkodean iirc Google digunakan untuk melarang penggunaan pengecualian). Pengecualian yang diperiksa di Java tentu saja merupakan eksperimen yang unik dan dengan demikian menarik, tetapi fitur tersebut mendapatkan begitu banyak kredit buruk selama sejarahnya ... sebagian besar orang hanya mengolahnya kembali saat runtime (walaupun ini mungkin hanya terkait dengan sintaks).
wvxvw
Saya lebih akrab dengan klasifikasi pengecualian Common Lisp, di mana mereka mencoba (walaupun dengan sedikit keberhasilan) membaginya sesuai dengan tingkat ancaman yang mereka ajukan pada program. misalnya serious-conditionvs simple-condition. Saya juga sekarang membaca JL Austing, di mana dia mengklasifikasikan kesalahan (tidak terkait dengan pemrograman) ke dalam kelompok berdasarkan pada bagaimana sistem gagal melakukan tugas (mis. Bagian yang tidak tepat digunakan vs niat yang tidak tulus). Yang tidak segera berlaku untuk pemrograman, tetapi mungkin setelah beberapa perbaikan.
wvxvw
@Wandering Logic Saya telah upvoded karena Anda telah menjelaskan mengapa C ++ excpetios adalah sux dan dimasukkannya fitur yang terdidik dapat merusak bahasa.
Val
@ wvxvw very strong objectionPengecualian terhadap C ++ berasal dari dua fakta: tidak ada finallykonstruk dan tidak ada orang lain yang menggunakan pengecualian. Masalah pertama juga memperparah masalah kedua. Yaitu, Ketika Anda tidak punya finally, Anda tidak bisa menutup sumber daya ketika pengecualian terjadi. Karena tidak ada yang menggunakan pengecualian, semua fungsi / API menghindarinya, Anda harus berinvestasi banyak membangun kembali seluruh infrastruktur C ++ tradisional yang membungkus semua fungsi dengan pengecualian Anda untuk mulai mendapatkan manfaat darinya dalam kode Anda. Tetapi kurangnya finallymembuat pendekatan ini tidak mungkin juga.
Val
@wvxvw: Konvensi Google melarang pengecualian di seluruh batas modul (.so). Ini karena pengecualian dalam C ++ menggunakan informasi jenis run-time (RTTI), dan Linux tidak melakukan pekerjaan yang baik dalam mengimplementasikan mengetik run-time. Di Linux, Anda hanya dapat melewatkan jenis run-time dengan andal di antara modul jika Anda mengompilasi modul dengan versi yang sama dari kompiler yang sama dan ditautkan dengan versi libstdc ++ yang identik. Sungguh ini adalah penolakan C ++ secara umum oleh komunitas Linux, bukan penolakan pengecualian secara khusus.
Pengembaraan Logika
3

Izinkan saya menunjukkan bahwa pengecualian adalah kasus efek komputasi . Efek komputasi lainnya adalah keadaan dapat berubah, I / O, non-determinisme, kelanjutan, dan banyak lainnya. Jadi pertanyaan Anda dapat ditanyakan secara lebih umum: bagaimana kita membentuk hierarki efek komputasi, bagaimana kita mengaturnya, dan mengapa kita memiliki yang kita miliki, dan bukan yang lain, dll.

Andrej Bauer
sumber
1
Saya pikir ini sama sekali tidak relevan. Pertanyaannya bukan tentang memodelkan gagasan pengecualian, tetapi tentang memetakannya ke kesalahan - saya pikir cara yang tepat untuk menggambarkannya dari perspektif PLT akan menjadi teori hierarki pengecualian.
Gilles 'SO- stop being evil'
Hmm, kamu benar. Saya memperbaiki jawaban untuk menunjukkan ini, tapi saya pikir tidak perlu menghapusnya. Bagaimana menurut anda?
Andrej Bauer