例外階層の理論はありますか?


18

私は、何らかの方法で例外を持っている多数のプログラミング言語に精通していますが、2つの「病的な」傾向を目の当たりにしました。

  1. 例外の一般的なパターンや階層はないようです。基本的にすべての言語は独自のバージョンをロールし、例外が標準になった場合、標準で見つかる例外の種類はかなりarbitrary意的です(ほとんどの場合、ソースコードの読み取りなど、言語ツールの作成中に実装された例外デバッガーを起動するための文字列または例外、またはファイルが見つからない場合に発生する例外など)

  2. 言語で定義された例外がユーザープログラムで再利用されることはほとんどありません。通常、1つまたは2つの一般的な例外があります(たとえば、「実装しない」)。ほとんどの場合、プログラマは独自の例外を作成します。(たとえば、これを新しい数値型または新しいコレクション型の作成と比較してください)。

これは私にとってひどい省略のようです。ユーザープログラムでどのような種類のエラーが必要になるのか、誰も知りません。私は、数値型、コレクション、オブジェクトシステムなどに似た一種の素晴らしい階層が存在することを望んでいました。

さらに悪いことに、GoolgeとWikipediaはこの問題に関してほとんど助けを提供していません。これまでのところ、機能の例外に関する論文を見つけただけです。

このペーパーでは、遅延関数型プログラミングは組み込みの例外処理メカニズムを不要にするだけでなく、例外を使用するプログラムを開発および変換するための強力なツールを提供すると主張します。

(例外の機能理論、Mike Spivey、1988)

しかし、例外は良いと思います。例外を使用するプログラムを変換したくはありません。逆に、例外の使用を無秩序にしたいのです。

質問:

例外の理論はありますか?もしそうなら、それは何と呼ばれていますか?基礎となるものは、もしあれば、その基礎となるものは何ですか?


例外はやや新しい発明であり、Cの「longjmp」からいくらか生じた、おそらく20年未満の古いものです。ほとんどはOOPに接続されています。理想的な使用法/理論/ベストプラクティスはまだ進化中です。javaには、より精巧なモデルの1つがあります。ご指摘のとおり、例外に関連する「アンチパターン」が多数あります。これの一部は、「フォールトトレラントコンピューティング」の理論に関連していますが、これも全体的にはまだ初期段階にあるようです。
vzn

例外を継続理論のサブセットと考えることができます。参照en.wikipedia.org/wiki/Continuation
jmite

@jmite例外と継続は非常に異なります。例外はハンドラーに動的にバインドしますが、継続は静的にバインドします。一般に、少なくとも型が存在する場合、それ自体の継続を使用して例外を実装することはできません。たとえば、型付き例外と継続が相互にマクロ表現できないなどを参照してください。
マーティンバーガー

「言語で定義された例外がユーザープログラムで再利用されることはほとんどありません。」信用できる!カスタム例外を定義する必要はほとんどありません。たとえば、pythonとそのstdlibは、160個の例外などを定義します。考えている例外が定義されていない可能性は非常に小さいです。これらの例外の一部(ほとんど?)はあまり知られていない。たとえば、これLookupErrorすべてのカスタムコンテナで完全に問題ありませんが、多くの人はそれが存在することさえ知りません。
バクリウ

1
@jmiteこのトピックの前に例外があったもう1つの出会いは、ベンジャミンC.ピアスの本「Types and Programming Languages」です。関数の型を定義する文脈でエラーについて言及しているところ。つまり、彼の観点からすると、エラーは関数から返されたさらに別の値過ぎません(そうすることが許されれば、それらは型全体を形成する他の引数とともに)。
wvxvw

回答:


8

例外については多数の出版物があり、かなりの数の理論的調査があります。以下に、構造化されていない完全なリストといくつかの例を示します。申し訳ありませんが、現時点では、より焦点を絞った返信をする時間はありません。

  • B. Randell、ソフトウェアフォールトトレランスのシステム構造。
  • JB Goodenough。例外処理:問題と提案された表記。
  • JB Goodenough。構造化された例外処理。
  • BG Ryder、ML Soffa、例外処理の設計に影響を与えます。
  • D. Teller、A。Spiwack、T。Varoquaux、できるなら私をキャッチしてください。
  • X. Leroy、F。Pessaux、キャッチされていない例外のタイプベースの分析。
  • R. Miller、A。Tripathi、オブジェクト指向システムでの例外処理の問題。
  • S.ドリュー、KJゴフ、J。レーダーマン、ゼロオーバーヘッド例外処理の実装。
  • B. Stroustrup、例外の安全性:コンセプトとテクニック。
  • D. Malayeri、J。Aldrich、実用的な例外仕様。
  • H.中野、キャッチアンドスローメカニズムの建設的な形式化。
  • A. Nanevski、例外処理のための様相計算。
  • P. de Groote、例外処理の簡単な計算。
  • H.ティーレケ、国家の存在下での例外と継続について。
  • JG Riecke、H。Thielecke、型指定された例外と継続は相互にマクロ表現できません。
  • M. van Dooren、E。Steegmans、アンカー付き例外宣言を使用して、チェック済み例外の堅牢性と未チェック例外の柔軟性を組み合わせます。
  • JA Vaughan、Javaスタイルの例外の論理的解釈。
  • S.マーロー、S。ペイトンジョーンズ、A。モラン、Haskellの非同期例外。
  • B.ジェイコブス、F。ピーセン、フェイルボックス:確実に安全な例外処理。

わあ、どうもありがとう!肯定的な返事を得るために、私は数ヶ月かかります(それ以上ではないにしても):今、私はどこから始めればいいか分からない数冊の本の間で破れています!
wvxvw

2
これらの論文の多くは、プログラミング言語での例外の実装またはモデリングに関するものであり、例外階層の設計方法に関するものではありません。関連する論文までリストをトリムできますか?
ジル 'SO-悪であるのをやめる'

@Gilles元の質問は少し不明瞭でした。適切な例外としてカウントされるものは、主にアプリケーションに依存することを認識しています。例外に関する唯一の実際の理論上の問題は、(1)例外を介して無関係なモジュールを結合すること(これは、Javaに必須の例外仕様がある言語がないためです)、(2)モジュールのユーザーに期待されるエラーの種類を示すことのトレードオフです、および(3)コンパイラはエラー処理を支援します。私が見る限り、この難問に対する本当に説得力のある解決策はまだ見つかっていません。
マーティンバーガー

6

理論があるかどうかはわかりませんが、実用的な実験科学が生まれている可能性があります。

私が考えることができる最高の情報源は、Bjarne Stroustrup、The Design and Evolution of C ++、Addison-Wesley、1994です。私が正しく覚えている場合(非常に良い本であり、人々は私からそれを借り続けて返さないので、現時点ではコピーを持っていません)、例外に関する章があります。StroustrupのC ++委員会は、提案された機能が言語定義に追加する前に必要であるという多くの経験的証拠を必要としました。例外に関するWikipediaのページには、その本から次の引用があります。

1991年11月のパロアルト[C ++標準化]ミーティングで、個人的な経験とJim Mitchell(以前はSun、以前はXerox PARC)からのデータに裏打ちされた終了セマンティクスの議論の素晴らしい要約を聞きました。ジムは20年間にわたって6か国語で例外処理を使用し、ゼロックスのCedar / Mesaシステムの主要な設計者および実装者の1人として再開セマンティクスの初期の支持者でした。彼のメッセージは終了よりも再開よりも好まれました。これは意見の問題ではなく、長年の経験の問題です。再開は魅惑的ですが、無効です。彼はいくつかのオペレーティングシステムからの経験でこの声明を支持しました。主要な例は、Cedar / Mesaでした。これは、再開を気に入って使用した人々によって書かれましたが、10年使用した後、50万の回線システムに再開の使用は1つしかありませんでした。それはコンテキストの調査でした。このようなコンテキスト照会には再開は実際には必要ではなかったため、再開し、システムのその部分で大幅な速度の向上が見られました。再開が使用されたすべてのケースで、10年以上にわたって問題が発生し、より適切な設計がそれを置き換えました。基本的に、再開を使用するたびに、抽象化のレベルをばらばらに保つことができませんでした。再開が使用されたすべてのケースで、10年以上にわたって問題が発生し、より適切な設計がそれに取って代わりました。基本的に、再開を使用するたびに、抽象化のレベルをばらばらに保つことができませんでした。再開が使用されたすべてのケースで、10年以上にわたって問題が発生し、より適切な設計がそれを置き換えました。基本的に、再開を使用するたびに、抽象化のレベルをばらばらに保つことができませんでした。

C ++での本当の勝利はRAIIであり、これによりエラー時のリソースの割り当て解除がはるかに簡単になります。(これは、の必要性を廃止しないthrowtry- catch、それはあなたが必要がないことを意味しますfinally。)

私は彼らに例外が必要だと確信したのはジェネリックコンテナだと思います:コンテナライターは含まれているオブジェクトが返す必要があるかもしれないエラーの種類については何も知りません(それらを処理する方法ははるかに少ない)が、それらのオブジェクトをコンテナは、それらのオブジェクトのインターフェースが何かを知る必要があります。ただし、含まれているオブジェクトがどのようなエラーをスローするかについては何も知らないため、例外タイプを標準化することはできません。(反対に、例外タイプを標準化できれば、例外は必要ありません。)

人々が長年にわたって学んだと思われる他のことは、例外仕様を言語に正しく入れることが難しいということです。例:このために参照してくださいhttp://www.gotw.ca/publications/mill22.htm、またはこの:http://www.gotw.ca/gotw/082.htm。(C ++だけではなく、Javaプログラマーは、チェック済み例外と未チェック例外の経験について長い議論を持っています。)

例外の歴史について少し。古典的な論文は次のとおりです。JohnB. Goodenough:「例外処理:問題と表記法」Commun。ACM 18(12):683-696、1975。しかし、それ以前は例外が知られていました。Mesaは1974年頃にそれらを持っていましたが、PL / Iも持っていたかもしれません。エイダは、私はC ++の例外は最大で約1976年からバーバラ・リスコフのCLUプログラミング言語の経験によって影響を受けたと信じている1980年前に、例外メカニズムを持っていた で『CLUの歴史』:バーバラ・リスコフ---プログラミング言語の歴史II、トーマスJ.ベルギンジュニアとリチャードG.ギブソンジュニア(編)。頁471から510、ACM、1996


これは興味深いものであり、私はよりよく応答するためにさらに調査する必要があります。しかし、これまでのところ、C ++で例外を使用することには非常に強い反対があることを知っています(おそらく逸話ですが、例外の使用を禁止するために使用されていたGoogleのコーディング規約)。Javaチェック例外は確かにユニークで興味深い実験ですが、この機能はその歴史の中で非常に多くの悪い功績を上げました...ほとんどの人は実行時にそれらを単に投げ直します(ただしこれは構文に関連しているだけかもしれません)。
wvxvw

私はCommon Lispの例外の分類に精通しており、彼らは(ほとんど成功していませんが)プログラムに与える脅威のレベルに応じてそれらを分割しようとしました。例えばserious-conditionsimple-condition。また、私はJLオースティンを読んでいます。彼は、システムがタスクを実行できなかった方法に基づいて、エラー(プログラミングとは無関係)をグループに分類しています(不適切なパーツの使用と不誠実な意図など)。すぐにプログラミングに適用できるわけではありませんが、少し改良した後かもしれません。
wvxvw

@Wandering Logic C ++ excpetiosがsuxである理由と、教育された機能の組み込みが言語を破壊する可能性があることを説明したので、私は支持しました。
ヴァル

@wvxvw very strong objectionC ++の例外に対する例外は、2つの事実に由来finallyします。コンストラクトはなく、誰も例外を使用しません。最初の問題も2番目の問題を悪化させます。つまり、no finallyがある場合、例外が発生したときにリソースを閉じることはできません。誰も例外を使用しないため、すべての関数/ APIが例外を回避するため、すべての関数を例外でラップする従来のC ++インフラストラクチャ全体を再構築するために多大な投資をし、コードでそれらから利益を得る必要があります。しかしfinally、このアプローチが欠如していることも不可能です。
ヴァル

@wvxvw:Googleの規則では、モジュール(.so)の境界を越えて例外をスローすることを禁止しています。これは、C ++の例外がランタイム型情報(RTTI)を使用し、Linuxがランタイム型付けをうまく実装できなかったためです。Linuxでは、同じコンパイラの同じバージョンでモジュールをコンパイルし、同じバージョンのlibstdc ++に対してリンクした場合にのみ、モジュール間で確実にランタイム型を渡すことができます。実際、これはLinuxコミュニティによる一般的なC ++の拒否であり、具体的な例外の拒否ではありません。
さまようロジック

3

例外は計算効果のケースであることを指摘しましょう。他の計算効果には、可変状態、I / O、非決定論、継続などがあります。それで、より一般的にあなたの質問を尋ねることができます:計算効果の階層をどのように形成するのか、どのようにそれらを整理するのか、そしてなぜ他のものではなく私たちが持っているものがあるのか​​など。


1
これはまったく無関係だと思います。問題は、例外の概念をモデル化することではなく、エラーにマッピングすることです。PLTの観点から説明する正しい方法は、例外階層の理論になると思います。
ジル 'SO-悪である停止'

うーん、あなたは正しい。これを指摘するために答えを修正しましたが、削除する必要はないと思います。どう思いますか?
アンドレバウアー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.