静的型チェックが保守的すぎるのは不自然な例では何ですか?


9

プログラミング言語で概念、ジョン・ミッチェルは、静的な型チェックが原因で停止問題の(過度に厳格な)は、必ずしも保守的であることを書き込みます。彼は例として以下を与えます:

if (complicated-expression-that-could-run-forever)
   then (expression-with-type-error)
   else (expression-with-type-error)

誰かが実際に問題となる不自然な答えを提供できますか?

私はJavaが次のような場合に動的にチェックされるキャストを許可することを理解しています:

if (foo instanceof Person) {
    Person p = (Person) foo;
    :
}

しかし、私は、言語間の問題よりも、Java言語/コンパイラーの欠陥の必要性を考えています。


2
あなたが提供したJavaの例、静的な型チェックが保守的すぎるという不自然な例です。別の言い方をすれば、答えはあなたがどのタイプシステムを考えているかに依存します。ここで取り上げる例では、その例を処理できる型システムが常に存在します(型システムはその例では保守的ではありません)。どのタイプシステムでも、保守的すぎる例はいつでも見つかります。したがって、型システムを指定する必要があると思います。Javaの型システムが想定していたものと異なる場合、考えていたより具体的なものはありますか?MLスタイルの型推論?
DW

この例は静的なコード分析の 1つであり、型のチェックではなく「保守的」であると主張する人もいるかもしれません。「保守的」と定義すると役立ちます。おそらくすべての静的型システムは、動的システムと比較して「保守的」です。なぜなら、前者は定義によりコンパイル時により厳密だからです。ただし、動的チェックでも同様の(タイプに基づく)エラーが返される可能性があるため、どちらも実行時の方が厳密ではない可能性があります。ちなみに、言語のランタイム動的チェックキャストは欠陥ではありません。それらは、ほとんどの静的チェック言語であり、おそらく必要です。
vzn 2015

回答:


7

私は常に、アルゴリズムをまったく表現できないかどうかというより、利便性の問題として考えてきました。Mitchellの考案したプログラムのようなプログラムを本当に実行したい場合は、静的型付け言語で適切なTuring Machineシミュレーターを作成するだけです。

静的型システムの秘訣は、柔軟性があり、保守が容易なコードを記述できる場合にのみ、適切な種類の柔軟性を提供することです。

静的に型付けされた言語よりも動的に管理する方が簡単であると考えられるプログラム構造化手法の例をいくつか示します。

ジェネリックとコンテナー

ML(1973年頃)およびCLU(1974年頃)より前の静的型付き言語では、文字列の赤黒木、整数の赤黒木、浮動小数点数の赤黒木、または特定のタイプの要素の赤黒木Foo。ただし、静的にチェックされ、これらのデータ型のいずれかを処理できる赤黒ツリーの単一の実装を作成することは困難(おそらく不可能)でした。問題を回避する方法は、(1)型システムから完全に抜け出すことでした(たとえば:void * C)では、(2)何らかのマクロプリプロセッサを自分で作成し、必要な特定の各タイプのコードを生成するマクロを作成するか、(3)抽出されたタイプをチェックするLisp / Smalltalk(およびJava)アプローチを使用します。オブジェクトを動的に。

MLとCLUはそれぞれ、推論された型と明示的に宣言された(静的)パラメーター化された型の概念を導入しました。

サブタイプポリモーフィズム

Simula67(1967 年頃)およびHope(1977年頃)より前の静的型付き言語では、動的ディスパッチとすべてのサブタイプのケースをカバーしているかどうかの静的チェックの両方を行うことはできませんでした。多くの言語には何らかの形式のタグ付き共用体がありましたが、caseor switchステートメントまたはジャンプテーブルがすべての可能なタグをカバーすることを確認するのはプログラマの責任でした。

Simulaモデルに準拠する言語(C ++、Java、C#、Eiffel)は、サブクラスを抽象クラスに提供し、コンパイラは、各サブクラスが親クラスによって宣言されたすべてのメソッドを実装したことを確認できます。Hopeモデルに続く言語(SML / NJからHaskellまでのすべてのMLバリアント)には代数的サブタイプがあり、コンパイラーtypecaseはすべてのステートメントがすべてのサブタイプをカバーしていることを確認できます。

モンキーパッチとアスペクト指向プログラミング

動的型システムにより、さまざまなプロトタイピング手法がはるかに簡単になります。文字列から関数へのハッシュマップで型が表現される言語(Python、Javascript、Rubyなど)では、特定の型に依存するすべてのモジュールの動作を、それを表すハッシュマップを動的に変更するだけで簡単に変更できます。タイプ。

モンキーパッチを使用してプログラムの保守を困難にする明らかな方法はありますが、実際には「悪」ではなく「善」に使用できる方法もあります。特にアスペクト指向プログラミングでは、モンキーパッチングのような手法を使用して、仮想化ファイルシステムを指すようにファイルタイプを変更したり、「無料」のユニットテストインフラストラクチャを構築したり、単純な例外タイプを変更して、デバッグしやすくするために、ログメッセージがキャッチされるたびに出力します。

1970年代に主要な静的チェックのアイデアが利用可能になったジェネリックとサブタイプポリモーフィズムとは異なり、アスペクト指向プログラミングの静的チェックは(私が思うに)アクティブな研究分野です。2001年頃からAspectJという言語があることを除いて、私はそれについてあまり知りません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.