6

静的/強く型付けされたプログラミング言語で最も貴重なことは、リファクタリングに役立つことだと思います。APIを変更すると、コンパイラはその変更が何を壊したかを教えてくれます。

ランタイム/弱い型の言語でコードを書くことは想像できますが、コンパイラの助けなしにリファクタリングを想像することはできません。また、リファクタリングなしで数万行のコードを書くことも想像できません。

これは本当ですか?

4

5 に答える 5

12

タイプがチェックされるとき、それらがチェックされる方法と混同していると思います。ランタイムタイピングは必ずしも弱いわけではありません。

静的型の主な利点は、まさにあなたが言うことです:それらは網羅的です。コンパイラに任せるだけで、すべての呼び出しサイトがその型に準拠していることを確信できます。

静的型の主な制限は、表現できる制約が制限されていることです。これは言語によって異なり、ほとんどの言語は比較的単純な型システム(c、java)を持ち、他の言語は非常に強力な型システム(haskell、cayenne)を持っています。

この制限のため、タイプだけでは十分ではありません。たとえば、Javaでは、型は多かれ少なかれ型名の一致のチェックに制限されています。これは、チェックしたい制約の意味をある種の命名スキームにエンコードする必要があることを意味します。したがって、Javaコードに共通する多数の間接化とボイラープレートがあります。C ++は、テンプレートがもう少し表現力を高めるという点で少し優れていますが、依存型でできることに近づかないでください。より強力な型システムの欠点が何であるかはわかりませんが、明らかに、業界でそれらを使用する人が何人かいるはずです。

静的型付けを使用している場合でも、気になるすべてをチェックするのに十分な表現力がない可能性があるため、テストも作成する必要があります。静的型付けが定型文で必要とされるよりも多くの労力を節約するかどうかは、長年にわたって激怒している議論であり、すべての状況に対して簡単な答えがあるとは思いません。

2番目の質問について:

ランタイム型言語で安全にリファクタリングするにはどうすればよいですか?

答えはテストです。テストでは、重要なすべてのケースをカバーする必要があります。ツールは、テストがどれほど徹底的であるかを測定するのに役立ちます。カバレッジチェックツールは、コードの行がテストでカバーされているかどうかを通知します。テストミューテーションツール(jester、heckle)は、テストが論理的に不完全であるかどうかを通知できます。受け入れテストでは、作成した内容が要件に一致していることがわかります。最後に、回帰テストとパフォーマンステストにより、製品の新しいバージョンがそれぞれ最後のバージョンの品質を維持していることが確認されます。

適切なテストを実施することと、複雑な型の間接化に依存することの優れた点の1つは、デバッグがはるかに簡単になることです。テストを実行すると、コンパイラのエラーステートメント(c ++テンプレートエラーを考えてください)ではなく、テスト内で実行していることを明確に表す特定の失敗したアサーションを取得します。

使用するツールに関係なく、自信を持ってコードを作成するには手間がかかります。多くの場合、多くのテストを作成する必要があります。航空宇宙や医療制御ソフトウェアなど、バグに対するペナルティが非常に高い場合は、正式な数学的手法を使用してソフトウェアの動作を証明する必要があり、そのような開発には非常に費用がかかります。

于 2009-05-19T01:23:14.913 に答える
6

私はあなたの感情に完全に同意します。動的に型付けされた言語が得意であると思われる非常に柔軟性が、実際にはコードの保守を非常に困難にしているのです。本当に、実際にコードを変更せずにデータ型が重要な方法で変更された場合でも動作し続けるプログラムのようなものはありますか?

それまでの間、渡される変数の型を確認できますが、予期された型でない場合はどういうわけか失敗します。これらのケースを根絶するためにコードを実行する必要がありますが、少なくとも何かが教えてくれます。

Googleの内部ツールは実際にコンパイルを行い、おそらくJavascriptに対してタイプチェックを行うと思います。それらのツールがあればいいのにと思います。

于 2009-05-19T00:30:57.373 に答える
2

まず、私はネイティブのPerlプログラマーなので、静的型のネットを使ってプログラミングしたことはありません。OTOH私は彼らと一緒にプログラムしたことがないので、彼らの利益について話すことはできません。私が話すことができるのは、リファクタリングがどのようなものかということです。

静的型の欠如がリファクタリングの問題になるとは思いません。私が問題を見つけたのは、リファクタリングブラウザがないことです。動的言語には、実際に実行するまで、コードが実際に何をするのかがわからないという問題があります。Perlにはこれ以上のものがあります。Perlには、非常に複雑でほとんど解析できない構文があるという追加の問題があります。結果:リファクタリングツールはありません(ただし、リファクタリングツールは非常に迅速に機能しています)。最終的には、手作業でリファクタリングする必要があります。そして、それがバグをもたらすものです。

私はそれらを捕まえるためのテストを持っています...通常。私はしばしば、テストされていないコードの蒸し暑い山の前にいて、テストするためにコードをリファクタリングする必要があるが、リファクタリングするためにコードをリファクタリングする必要があるという鶏が先か卵が先かという問題を抱えています。いや。この時点で、何かを壊していないことを確認するために、非常に馬鹿げた高レベルの「プログラムは以前と同じように出力します」という種類のテストを作成する必要があります。

Java、C ++、またはC#で想定されている静的型は、実際には小さなクラスのプログラミング問題しか解決しません。これらは、インターフェイスに正しいラベルのデータが渡されることを保証します。ただし、コレクションを取得したからといって、コレクションに含まれていると思われるデータが含まれているとは限りません。整数を取得したからといって、正しい整数を取得したとは限りません。メソッドはUserオブジェクトを受け取りますが、そのユーザーはログインしていますか?

古典的な例:public static double sqrt(double a)Java平方根関数のシグネチャです。平方根は負の数では機能しません。署名のどこにそれが書かれていますか?そうではありません。さらに悪いことに、その機能が何をするのかはどこに書かれていますか?署名は、それが取るタイプとそれが返すものだけを示します。その間に何が起こるかについては何も述べておらず、そこに興味深いコードが存在します。一部の人々は、契約による設計を使用して完全なAPIをキャプチャしようとしました。これは、関数の入力、出力、および副作用(またはその欠如)の実行時テストを埋め込むこととして広く説明できます...しかし、それは別のショーです。

APIは単なる関数の署名以上のものであり(そうでない場合は、Javadocでそのような説明的な散文をすべて必要としないでしょう)、リファクタリングはAPIを変更するだけではありません。

静的に型付けされ、静的にコンパイルされた非動的言語がもたらす最大のリファクタリングの利点は、メソッドへのすべての呼び出しがどこにあるかを知っているため、非常に複雑なリファクタリングを実行するリファクタリングツールを作成できることです。私はIntelliJIDEAにかなりうらやましいです。

于 2009-05-20T04:36:50.527 に答える
1

リファクタリングは、静的に型付けされた言語であっても、コンパイラーがチェックできる範囲を超えていると言えます。リファクタリングとは、外部の動作に影響を与えることなく、プログラムの内部構造を変更することです。動的言語であっても、発生してテストすることが期待できることがまだあります。コンパイラーからの支援が少し失われるだけです。

于 2009-05-19T00:25:32.190 に答える
1

C#3.0でvarを使用する利点の1つは、コードを壊さずに型を変更できることです。タイプは同じように見える必要があります-同じ名前のプロパティが存在する必要があり、同じまたは類似のシグネチャを持つメソッドがまだ存在している必要があります。ただし、ReSharperのようなものを使用しなくても、実際には非常に異なるタイプに変更できます。

于 2009-05-19T00:56:38.290 に答える