web-dev-qa-db-ja.com

静的型付けはトレードオフに値しますか?

私はPython主に型安全性がない場所でコーディングを開始し、次にC#に移動し、Javaがある場所です。少し作業できることがわかりました。 Pythonの方が頭痛が少なくて済みますが、C#とJavaアプリははるかに複雑なレベルにあるため、Python a真のストレステストだと思います。

JavaとC#のキャンプでは、タイプセーフティを設定しないと音が聞こえます。ほとんどの人はあらゆる種類の恐ろしいバグを右に残しているので、その価値よりもトラブルになります。

これは言語の比較ではないため、コンパイル済みと解釈済みの問題には対処しないでください。 型の安全性は、開発のスピードと柔軟性にヒットする価値がありますか?なぜ?

動的タイピングの方が速いという意見の例を望んでいる人々へ:

「開発中に動的に型付けされた言語を使用します。これにより、フィードバック、ターンアラウンドタイム、開発速度が速くなります。」 - http://blog.jayway.com/2010/04/14/static-typing-is-the-root-of-all-evil/

110

プログラマーが動的に型付けされた言語の型について心配する必要がないのは、一種の神話です。

動的に型付けされた言語では:

  • 配列、整数、文字列、ハッシュテーブル、関数参照、ディクショナリ、オブジェクトなどを使用しているかどうかを知る必要があります。

  • オブジェクトの場合は、それがどのクラスに属しているかを知る必要があります。

  • これらの型の1つを別の型であると予想される変数または関数パラメーターに割り当てると、ほとんどの場合エラーになります。

  • より低いレベルでは、たとえばTCPパケットを入力する場合は、ビット数や符号付きと符号なしのどちらが頻繁かなどを考慮する必要があります。

  • 空の文字列が本当に必要な場所でゼロを取得するという問題が発生する可能性があります。つまり、型の不一致のバグをデバッグしています。唯一の真の違いは、コンパイラーがエラーをキャッチしていないことです。

  • 関数のパラメーターをコードで文書化するのではなく、コメントで文書化する傾向があるため、入力を大幅に節約することすらありません-と主張します。これが、doxygenスタイルのコメントブロックが、動的に型付けされたコード全体で実際にはるかに人気がある理由です。静的に型付けされた言語では、ほとんどの場合、ライブラリに対してのみ表示されます。

動的に型付けされた言語でのプログラミングは、コンパイラーが常に背負っているわけではなく、経験豊富なプログラマーがそうではないので、feelが快適ではないというわけではありません静的型付けがとにかく検出する種類のバグを見つけて修正するのは難しい傾向がありますが、これは効率型の向上やバグ率の低下とは完全に別の問題であり、静的型付けでも動的型付けが最善です。

164
Karl Bielefeldt

タイプが強くなるにつれて、それらはあなたをより助けることができます— if戦うのではなく、正しく使用します。問題の空間と論理エラーを反映するように型を設計すると、実行時のクラッシュや無意味な結果ではなく、コンパイル時の型の不一致が発生しやすくなります。

124
geekosaur

免責事項:私はタイプ好きです;)

あなたの質問は答えるのが難しいです:それらは何ですかトレードオフ

私は極端な例をとります:Haskell、それは静的に型付けされています。おそらく、実際に存在する最も強く型付けされた言語の1つです。

ただし、HaskellはGeneric Programmingをサポートします。これは、特定の概念(またはインターフェース)に準拠する任意の型で機能するメソッドを記述するという意味です。

さらに、HaskellはType Inferenceを使用するため、変数の型を宣言する必要はありません。 Pythonインタプリタがプログラムを実行してそれらを計算するのと同じように、それらはコンパイル中に静的に計算されます。

私は静的型付けに苛立ち、ほとんどの人が実際に何か他のものについて不平を言っていることを発見しました(冗長性、ある型を別の型に切り替えることの苦痛)、しかし静的に型付けされている間、Haskellはそれらの問題を示しません...


簡潔さの例:

-- type
factorial :: Integer -> Integer

-- using recursion
factorial 0 = 1
factorial n = n * factorial (n - 1)

組み込みのサポートとは別に、簡潔にすることは困難です。

一般的なプログラミングの例:

> reverse "hell­o" -- Strings are list of Char in Haskell
=> "olleh"
> reverse [1, 2, 3, 4, 5]
=> [5,4,3,2,1]

型推論の例:

> :t rever­se "hell­o"
:: [Char]

これは簡単に計算できます:

  • "hello"Charのリストです([Char]と表記)
  • reverseを型に適用[A]は型を返します[A]

試してみてください ブラウザで

78
Matthieu M.

静的型付け言語と動的型付け言語の両方が好きです。私にとってのタイプセーフの2つの最大の利点は次のとおりです。

1)多くの場合、関数が純粋に型シグネチャから何を行うかをかなり推測できます(これは、Haskellのような関数型言語で特に当てはまります)。

2)大幅なリファクタリングを行うと、コンパイラは、すべてを機能させるために必要なすべてのことを自動的に通知します。 C++で何かをリファクタリングするとき、私の手順は多くの場合、a)変更したい部分を変更し、b)すべてのコンパイルエラーを修正します。

37
dfan

個人的には、タイプセーフは現在の仕事でより速く開発するのに役立つと思います。コンパイラーは、入力するのとほぼ同じように、多くの妥当性検査を行ってくれるので、実装しているビジネスロジックにさらに集中できます。

結論としては、ある程度の柔軟性は失われますが、タイプの問題を追跡するために費やす時間を稼ぐことができます。

29
Michael K

議論については多くの強い意見がありますが、明らかにこれは実際には意見の問題ではなく、事実の問題です。それで、私たちは経験的研究を見る必要があります。そしてそれからの証拠は明らかです:

はい、静的型付けはトレードオフの価値があります—少しだけでなく、実際には実質的に。実際、確かな証拠は、静的型付けにより、コード内のバグの数を少なくとも15%削減できることを示しています(これは推定値が低く、実際の割合はほぼ確実に大きくなります)。それは驚くほど高いの数値です。静的型付けの支持者でさえ、これほど劇的な違いがあるとは考えていなかったと思います。

これを考慮してください。プロジェクトのバグを一晩で15%削減する簡単な方法があると誰かがあなたに言った場合、それは簡単なはずです。1 それはほとんどことわざの銀の弾丸です。

証拠は、Zheng Gao、Christian Bird、およびEarl T. Barrによる論文 To Type or Not to Type:Quantifying Detectable Bugs in JavaScript に掲載されています。私は、皆さんにそれを読むことをお勧めします。これは、模範的な研究を示す上手に書かれた論文です。

著者がどれだけ厳密に分析を行ったかを簡潔に要約することは困難ですが、これは(非常に大まかな)概要です:

TypeScript Flow はJavaScriptに基づく2つのプログラミング言語であり、互換性は維持しながら、型ヒントと静的型チェックを追加します。これにより、タイプごとに既存のコードを拡張し、タイプチェックすることができます。

研究者たちは、GitHubからJavaScriptで記述されたオープンソースプロジェクトを収集し、解決されたバグレポートを調べて、報告された各バグを、TypeScriptまたはFlowの静的型チェッカーによってキャッチされるコードに削減しようとしました。これにより、静的型付けを使用して修正できるバグの割合の下限を見積もることができました。

研究者は、分析でタイプに関連しないバグがタイプに関連していると見なされないように、厳密な予防策を講じました。2

過去の研究と比較して、この新しい研究には特別な長所があります。

  • direct 静的 vs 動的タイピングの比較があります。JavaScriptとTypeScriptの唯一の違いがあるため、交絡因子は(もしあれば)わずかです。/Flowはタイピングです。
  • TypeScriptとFlow(つまり、異なる型システム)の両方をチェックし、さまざまな人に(手動の)型注釈を再現してバグを修正させることで、複数の次元にまたがるレプリケーションを実行します。そして、さまざまなプロジェクトの多数のコードベースでこれを実行します。
  • この論文では、修正可能なバグに対する静的型付けの直接的な影響を測定しています(より曖昧な品質ではありません)。
  • 著者は、何をどのように前もって測定するかについての厳密なモデルを定義します。さらに、彼らの説明は信じられないほど明確で、欠陥の分析が容易になります(研究論文が攻撃に身を任せれば、常に良いことです。攻撃がその主張を掘り下げることができなければ、さらに強力になります)。
  • それらは適切な 電力分析 を実行するため、サンプルサイズは十分であり、その後の統計分析は気密です。
  • それらは交絡の説明を除外するために過度に保守的であり、単一の可動部分のみを測定します。さらに、タイプを含めることですぐに修正可能なバグに分析を限定し、タイピングに対応するためにより高度なリファクタリングが必要になる可能性があるものは除外します。したがって、実際には、その影響はおそらくはるかに大きいですが、確かに彼らが報告したものよりも小さくはありません。
  • そして最後に、わずかな効果は見つかりませんが、驚異的な違いがあります。非常に保守的な手順にもかかわらず、95%の信頼区間の下限でさえ、最小限の型チェックを追加するだけで消えるバグが少なくとも10%あることがわかりました。

この論文にまだ誰も発見していない根本的な欠陥がない限り、ほとんど無料で、静的な型付けの大きなメリットが最終的に示されます。4


歴史的に、プログラミングにおけるタイピングの分野の研究は、長い間、証拠がまったくまったく明確でなかったため、根本的に始まりました。これは、体系的な実験を行って静的​​ vs 動的型付けの効果を調べるのは簡単ではないためです。体系的な実験では、調査している効果を分離する必要があります。残念ながら、タイピング分野はプログラミング言語に関連付けられているため、その影響を分離することはできません。

実際には、 were プログラミング言語があり、さまざまな方言で静的型と動的型の両方を使用できました(例:VB with Option StrictOnまたはOff、または静的に型付けされたLISP)。ただし、これらは直接比較にはあまり適していませんでした。最も重要なのは、直接比較できる十分に大きなコードベースが存在しなかったためです。テストの被験者が言語の静的または動的に型付けされたバリアントでタスクをランダムに解決する「実験室の設定」でせいぜいそれらを比較できます。

残念ながら、これらの人工的なプログラミングの割り当ては、実際の使用法をうまくモデル化していません。特に、それらの多くはスコープが小さく、テキストの半分のページに要約できる明確に定義された問題を解決します。

幸いなことに、TypeScript、Flow、JavaScriptは実際には静的型付けを除いて同じ言語であり、サンプルとなるコードとバグの広範な実世界のデータセットがあるため、これは過去のことです。


1 元の紙からの引用に触発されました。

2 私はこれに完全に満足しているわけではありません。静的に型付けされた言語の主な長所の1つは、表面的に型に関係のない問題を静的に型チェックできる方法で表現できることです。これにより、多くの論理エラーが型エラーに変換され、劇的に静的型付けによって捕捉できるバグの割合が増加します。実際、この論文ではタイプに関係のないバグを大まかに分類しており、それらの大部分は実際には静的タイピングによって捕捉される可能性があると私は主張しています。

 私はだれでも、特に動的型付けの支持者に、分析で対処されていない欠陥を見つけるように勧めます。多くはあると思いますが(あるとしても)、潜在的な欠陥が結果を大きく変えることはないと確信しています。

4 実際の大規模プロジェクトでの静的型付けの実際のコストは、アーキテクチャーの自然な部分になり、簡素化計画にさえなる可能性があるため、存在しないと思います。静的型エラーの修正には時間がかかりますが、後で発見されたエラーよりもはるかに少ないです。これは広範囲にわたって経験的に研究され、何十年もの間知られています(たとえば、 Code Complete を参照)。

14
Konrad Rudolph

型の安全性は、開発のスピードと柔軟性に影響を与える価値がありますか?

ですから、これはあなたがしていることに帰着します飛行機のバックアップシステムをプログラミングしている場合は、タイプセーフがおそらく最適です。

動的言語プログラミングと静的言語プログラミングは、実際には2つの異なる動物です。どちらにも、根本的に異なるアプローチが必要です。ほとんどの場合、静的と動的の間のアプローチ方法を移植できますが、他の利点を失うことになります。

それは本当に考え方です。一方が他方より優れていますか?それは本当にあなたが誰であるか、そしてあなたの考えに依存します。エラーが発生する余地が多すぎると感じているため、私が一緒に仕事をしている人のほとんどは、動的言語に触れる必要がない場合は触れません。彼らはこれを考えるのは間違っていますか?いいえ、もちろんそうではありませんが、コーディングスタイルを適用するアプローチが動的な環境では機能しないことに気付いたという意味です。私がユーザーグループに行く他の人々は、まったく逆です。静的型付けは、特定のタイプの問題を解決するためのアプローチを制限するため、扱いにくいと感じています。

正直言って、JavaScriptとC#の間でよくジャンプします。現在、両方の言語を知って作業することは、お互いにある程度影響を及ぼしますが、実際には、私がそれぞれに記述したコードは、他の言語とはまったく異なって見えます。それらは根本的に異なるため、異なるアプローチが必要です。私が見つけたのは、「これはX言語でこれを行うのが非常に難しい」という考えに気づいた場合、あなたのアプローチはおそらく少しずれているということです。ここに例があります、人々は物事の「Pythonic」方法について話します。つまり、Python言語は問題を容易にするために機能する方法があるということです。他の方法でそれを行うと、一般に困難で面倒になります。言語がどのように機能するか、それが実際に機能するかどうかは、動的言語と静的言語でまったく同じです。

12
kemiller2002

最近尋ねられた同様の質問がありました: ウェブサイトの動的言語と静的型言語

私の答えの核心を言い換えると:

システムが大きくなるにつれて、静的に型付けされた言語はコンポーネントレベルでの堅牢性を保証し、システムレベルでの柔軟性を保証します。

はい、Javaは厳密に入力されており、はい、Javaは悪いことではありません。それはひどいです。素晴らしいプラットフォームとエコシステムですが、これまでで最悪の言語の1つ(実際には使用されています))。
しかし、それから推測すると、厳密なタイピングはうんざりするだけの誤りです。これは、PHPを指して動的なタイピングが悪いと推測するようなものです(これも問題ありません。ゆっくりと改善されています。それをお伝えします)。

個人的に、私は開発のほとんどを静的型システムを持つ haXe で行っています。 Javaの場合よりも大幅に表現力が高いだけでなく、型の推論のために必要な労力がはるかに少ないだけでなく、オプションでもあります。邪魔になった場合は、バイパスするだけです。 。

タイプセーフは機能です(これは、多くの高水準言語が正しく理解できないものです)足元に自分を撃たないようにする
そして、コードタイプを自由にチェックするオプションがあれば、動的に型付けされた成功した言語については、単により良いでしょう。
たとえば、私は確かにRubyの実験を楽しんでいましたが、それは主にRubyが完全にオブジェクト指向であり、コンパイル時の型システムの存在と完全に直交しているためです。

静的型システムが目障りであるという主張は、優れた静的型システムの知識の欠如に単に基づいていると思います。正しく機能する言語はたくさんありますが、haxeはそのうちの1つであり、間違いなくその点で最高とは言えません。

HaXeコードの例:

class Car {
    public function new();
    public function wroom() trace('wroooooooom!')
}
class Duck {
    public function new();
    public function quack(at) trace('quackquack, ' + at + '!')
}

function letQuack(o) o.quack();
letQuack(new Car());
letQuack(new Duck());

これにより、コンパイル時エラーが発生します。

Car should be { quack : Void -> Unknown<0> }
Car has no field quack
For function argument 'o'
Duck should be { quack : Void -> Unknown<0> }
Invalid type for field quack :
to : String -> Void should be Void -> Unknown<0>
For function argument 'o'

タイプセーフティに多大な労力を費やさなければならなかったとは本当に言えません。

テストがあるので、タイプセーフは必要ないと言っても、もっとばかげています。テストを書くことは退屈で反復的です。そして、私は実際にテストを書きたくありません。ただ見つけるために、Carのインスタンスはたわむれず、Duckは誰かがたたかむ必要があります。

結局のところ、オーバーヘッドタイプの安全性にどれほどの費用がかかったかに関係なく、最終的には償却されます(Java-でもそれほどではないかもしれませんが)。

7
back2dos

場合によります。

人間の故障モードは統計的であることがよくあります。強力な型チェックにより、いくつかの特定のタイプの人的障害(バグのあるコードの原因)の可能性が低減します。しかし、失敗する可能性があるからといって、必ずしもそうなるとは限りません(マーフィーは非理解です)。

この潜在的な障害の可能性の減少がコストに見合うかどうかは、状況によって異なります。

原子力発電所またはATCシステムのコードを記述している場合、人的故障モードの削減は非常に重要な場合があります。仕様がなく、障害の影響がほとんどないウェブサイトのアイデアを迅速にプロトタイピングしている場合、障害モードまたは確率の低下により、何も購入されない場合がありますが、開発時間(キーストロークの増加など)にかかる可能性があります。そして、必要な現在のタイプを記憶することにより、気を取られた脳細胞に。

5
hotpaw2

なんらかの理由で、オブジェクトのタイプに関連するエラーは発生しなくなりました。 C#などの言語では、コンパイラーが検出可能なタイプセーフティエラーを発生させるよりも、ランタイムキャストに関連するエラーを発生させる可能性が高くなります。これは、通常、静的な静的性を回避する必要があるために発生します。型付けされた言語。 Rubyを書くとき、コードはオブジェクトのタイプをかなり強く示唆する傾向があり、REPLの可用性は、目的のメソッド/属性が存在することをすでに実験的に確認していることを意味します。基本的に同じことを行う単体テストがあるので、Rubyでタイプセーフティの問題に遭遇することもめったにありません。

しかし、それは、静的に型付けされたシステムが実際よりも優れているわけではないということではありません。

静的に型付けされた言語では、型systemも実際には重要です。一例として、関数型言語のSomeモナド(type <Some>:= yes x | no)のようなものを使用すると、ほとんどの型システムに共通する恐ろしいNullReferenceExceptionを本質的に防ぐコンパイル時のチェックが得られます。パターンマッチングコードを実行すると、null条件の処理に失敗したことを示すコンパイル時エラーが発生します(そのメカニズムを使用して型を宣言した場合)。 F#でパイプライン演算子|>のようなものを使用すると、同様のタイプのエラーも減少します。

Hindley–Milnerの静的型付けの伝統では、型がインターフェイスXをサポートすると主張することを保証する以上のことを実現できるものを構築できます。これらのものが得られたら、静的型付けシステムが多くなると思いますより貴重。

それが選択肢ではない場合、C#のDesign By Contract拡張機能は、静的型システムの価値を高めるメカニズムの別のセットを追加できますが、それらの機能パラダイムのいくつかよりもさらに規律が必要です。

5
JasonTrue

タイプはインターフェースの制約であるため、ユニットテストでテストする必要があるもののサブセットであり、多くのトレードオフが類似しています。

  • 静的型は、コードが型システムで表現できる要件を満たしているかどうかについて、フィードバックを最小限に抑える機能(顧客のフィードバックやより高いレベルのテストなど)の構築からの遅延と引き換えに、以前のフィードバックを提供します。
  • コードが特定の要件を満たしていることを知ると、リファクタリングとデバッグが容易になりますが、インターフェイスの変更と要件の変更にオーバーヘッドが追加されます。
  • 特に、静的に型付けされた言語が強制を欠いている場合、バグを引き起こすデータで使用されているコードに対する追加のセキュリティが提供されます(条件とアサーションの必要性が減少します)が、制限が厳しすぎるため、ユーザーはデータをマッサージするためにより多くのコードを書く必要があります受け入れ可能な形式(明示的な型キャストなど)。
  • 明示的な型注釈は、コードを読み取る際の理解に役立ちます。また、冗長または不要な情報を含むコードを混乱させる可能性があります。
  • 実装によっては、簡潔さを損なう可能性があります。これは、型注釈が必要または推論されるかどうか、型システムが一般的な型/インターフェースをどれだけ適切に表現できるか、構文、および型システムで表現できる制約(つまり、同じテストの方が単体テストよりも言語機能として簡潔である可能性がありますが、テストするつもりはなかった可能性があります)。
  • さらに(TDDとは関係ありません)、静的型はコンパイル時の最適化に役立ちますが、その際、型のチェック(およびそれらのチェックと最適化の実行に時間がかかる)が必要となり、データが型に制限されている場合は、より適切な最適化を行うことができます。ハードウェアにうまく対応します。これにより、パフォーマンス要件のあるコードの開発が容易になりますが、これらの制約にうまく適合しないコードでは問題が発生する可能性があります(ポイント3のとおり)。

要約すると、動的言語はプロトタイピングに特に役立ちますが、コードが正しいことを確認する必要がある場合は、強力な型システムを使用する必要があります。

4
T.R.

はい、間違いなく。厳密に型指定された言語とPython(Pythonは厳密に型指定されています)の両方を使用すると、1つ目にわかることは、動的言語で最もよく記述されたコードは、厳密に型指定されたコードと同じ規則の多くに従うことです。動的型付けは、シリアライゼーションとデシリアライゼーションに非常に役立ちますが、他のほとんどの場合、実際にはあまりメリットがありません。そして、ほとんどのコードがシリアライゼーション関連でない限り、無料のエラーチェックを行わないのはなぜですか?

3
Mason Wheeler

モーガン、私はあなたが試すべき面白いアイデアを得ました:静的+動的型付けです。あなたはPython、C#、Javaについて言及しました。 Pythonの.NETとJavaの両方への適切なポートがいくつかあることをご存知ですか?どちらの場合も、ポートを使用すると、これらのプラットフォームのライブラリを使用したり、既存のコードと相互運用したりできます。これはあなたにいくつかの可能性を与えます:

  1. レガシーコードを静的で柔軟性のない言語にしてください。新しいものにはPythonを使用してください。
  2. Pythonを使用して、成熟したプラットフォーム上で新しいものをプロトタイプ化します。より成熟した言語で保持したいコンポーネントを再コード化します。
  3. 頻繁に変更する部分には動的言語を使用します。
  4. おそらく、動的言語を使用して、実行中のコードの変更などのアイデアを試してください。
  5. 強く型付けされた言語を使用する重要な部分を除いて、すべて動的言語で行います。

私はこれらのアプローチを90年代後半まで使用して、C/C++での開発の苦痛を回避しました。ネイティブライブラリと、場合によってはパフォーマンスが必要でした。それでも、構文、柔軟性、安全性などを改善する必要がありました。そのため、正しいトレードオフを実現するために、これらを注意深く組み合わせていました。多くの場合、実際には、言語全体とレガシーコードを別の言語/プラットフォームに捨てるよりも優れていました。

(注:答えはすでにそれを言っていますが、その動的型付けを再度強調したいです!=いいえ/弱い型付け。多くの動的型システムは、内部で強い型付けを使用します。型の動的を作るものについて私が考える方法は、変数の型は実行時に決定され、型注釈を必要としないか、実行時に変更される可能性があります。

3
Nick P

LISPで記述された非常に複雑なシステムが数多くあり、静的型付けが必要であるというLisperの不満を聞いたことはありません。私がそれを使用したとき、静的型システム(およびCommon LISPで静的に型を指定できます)がキャッチするほど速度が低下した問題を覚えていません。

さらに、主流の静的型付け言語は、エラーをキャッチするのにあまり適していないようです。レイアウトを設計する際に重要なのは、特定の数値が、intunsignedfloat、またはdoubleであるかどうかではなく、ページ上の垂直方向の測定値であることです。一方、コンパイラーは、安全でないと思われる型変換にフラグを立てることがよくあります。縦軸の測定値と文字列の文字数を追加できます。静的型システムのこの弱点は、シモニーのハンガリー表記法の背後にある元のアイデアであり、醜い役に立たないものに改造されました。

3
David Thornley

私はこの質問がたくさん出てくるのを見ます、そしてあなたのソフトウェア品質(そしてバグの欠如)はあなたの開発プロセス、あなたのシステムがどのように設計されているか、そしてあなたとあなたの仲間のコード品質へのコミットメントにもっと関係があると思います。

私の最後の仕事は主にpython開発でした。私は国際的な大規模Webホスティング会社で働いていて、米国、カナダ、韓国に開発チームがいました。カスタムpythonユーザーがドメイン名とWebホスティングアカウントを管理できるようにするフロントエンドカスタマーアプリ用のWebフレームワーク。バックエンド:すべてpython too。Python web個々のサーバーと通信して、新しいWebホスティングサイトのプロビジョニング、新しいブログの作成、ネームサービスシステムでのDNSエントリの作成などを行うサービス。現在の仕事では、クライアントアプリはすべてJavaで、主な製品はJavaとflashの混合です。カスタムJava以前のアプリのWebフレームワーク、新しい内部ツールの改札です。

両方で働いていたので、この質問は私がそれを見るたびに私を悩ませます。動的に型付けされた言語を使用していて、実際にコードをテストする場合は問題ありません。システムが適切に設計されていて、標準に従っている場合は、問題ありません。コンパイラーのチェックタイプが不足しているために発生した多くのバグはありませんでした。私のJava今日の仕事と同じように、ほとんどのバグは論理的なエラーでした。

2
LGriffel

型の安全性は、開発のスピードと柔軟性に打撃を与える価値がありますか?どうして?

静的型付けは、ソフトウェアのライフサイクル全体での開発のスピードと柔軟性の正味increaseです。これにより、全体の労力と不便さが軽減されますが、多くの労力と不便が前に移動し、目立つようになります。機能するコードを持つことへの入り口の障壁は高くなりますが、(型チェッカーを満たすことによって)その障壁を超えると、そのコードの拡張と保守にかかる作業ははるかに少なくなります。

次の理由により、ソフトウェア開発には常にいくつかの問題があります。

  • 達成しようとしていることに固有の複雑さ

  • 人間の固有の誤り可能性。特に、より複雑なことをしようとすると、間違いが増えることを考えると

遅かれ早かれ、これらの課題に対処するために時間をかける必要があります。それを回避する方法はありません。静的型付けは、これらの課題に後からではなく早く対処するだけです。後で間違いを発見するため(ifの質問ではなく、whenの場合)、その間違いを修正するのにかかるコストが高くなるため、早い方が遅いより優れています。

実行時に発生する型関連の例外をデバッグするよりも、型チェッカーによって報告された間違いを修正する方がはるかにコストがかかりません。型チェックをランタイムに据え置くことは、ラグの下で問題を一掃するだけです。

2
Jordan

あなたはそれに対して真に客観的な答えを得るつもりはありませんが、私の経験では、タイプセーフは非常に貴重ですntilあなたはTDDをマスターします。コードの前にテストが記述されているユニットテストの対象範囲が広いと、コンパイラチェックが面倒になり、実際に邪魔になります。

2
pdr

はい。

PHPアプリケーションでは、タイプがJavaまたはC#のように「強力」ではありません。通常、「タイプのシミュレーション」を終了しました。不適切な自動変換またはデータの検証を回避するため。

動的型言語はO.S.に適していますスクリプトと簡単な小さなアプリ。複雑なアプリではありません。

概要:「弱い型」または「動的な型」のプログラミング言語、または複雑なビジネスアプリケーション用の「強い型」のプログラミング言語を選択する必要がある場合、を選択しますタイプ "プログラミング言語

0
umlcat

一歩下がって、動的タイピングがいつ問題を引き起こすかを検討することは価値があると思います。

1つのケースは、コードブランチがまったくテストされていない場合ですが、率直に言って、テストされていないコードは、動的型付けが使用されているかどうかに関係なくバグがある可能性があります。

もう1つのより微妙な問題は、不完全な代替可能性です。

型が完全に間違っている場合、特定のコードパスが使用されない限り、すぐに検出される可能性があります。

一方、型が不完全な置換である場合、コードはほとんど機能するかもしれませんが、かなり後になるまで検出されない微妙な方法で壊れます。

プログラミングで最も一般的な2つの型は、数値と文字列です。多くの動的言語では、それらは互いに不完全な代替物です。たとえば、文字列が期待される場所に数値を指定した場合、またはその逆の場合、javascriptまたはphpを使用すると、プログラムはエラーを発生させることなく実行されますが、かなり微妙な方法で誤動作する可能性があります。

Pythonはその特定の問題を回避しました。数値と文字列は決して相互に代用されるものではなく、一方が期待される場所で使用しようとすると、通常、迅速な障害が発生します。

しかし、それは不完全な代替可能性の問題を完全には避けませんでした。異なるタイプの数は、互いの不完全な代用となる可能性があるため、異なるタイプのシーケンスも同様です。


ここで得ているのは、静的型と動的型の利点とコストを一般的な方法で比較することは不可能だと思います。なぜなら、利点とコストの両方が、言語の静的型または動的型の特定のバリエーションに依存しているためです。使用します。

0
Peter Green

これは私自身の意見ですが、いいえ、タイプセーフに価値があるとは思いません。一秒もありません。

私は長い間開発者でした。 c ++、c#から始めて、javascript(node.jsを介したフロントエンドとバックエンド)に移動しました。私はJavaScriptで開発してきたので、生産性が飛躍的に向上し、タイプベースの言語を使用すると実際に悪化します。私もコンパイルに反対しています。今はすべてをランタイムにしたいと思っています。解釈された言語は、プログラミングへの私の愛着を本当に見つけた場所です。

タイプに関しては、何のメリットもありません。タイプはメモリ管理と同じように表示されます。完全に不要です。明日の言語は、型について何も知ることから開発者を完全に保護するはずです。コンピュータはタイプを理解し、開発者をその中に入れないようにする必要があります。

ここに例があります。私はちょうどSwift(Appleの新しい言語)を使用していて、1日前に実際にその名前に沿って動作することを期待して実行しようとしました:var n = 1/2は機能しませんでした。たとえば、ここで何が起こっているのかというと、悲しいことにvar n:Float = 1/2を実行する必要があることに気づきました。これにより、型システムがいかに嫌いであり、不必要な悪化がどれほどあるかを思い出しました。

ユーザー定義の型(クラスなど)も必要ない、と言ってもいいでしょう。タイプはまったく必要ありません。私が欲しいのはvarとオブジェクトだけです。任意のオブジェクトを任意のオブジェクトとして使用できる場所。また、オブジェクトは動的で常に変化しています。何が機能し、何が機能しないかに関してランタイムの問題になる場所。

開発者は、緩やかに型付けされた言語が大規模なプロジェクトに適していないと言うのが好きです。しかし、私はそれは反対だと思います。強く型付けされた言語は、大規模なプロジェクトにとっては恐ろしいものです。また、大規模なプロジェクトではjavascriptが機能しないと言う場合は、node.js/javascriptでバックエンドをすべて実行している400億以上の会社のUber、またはPHPで始まったFacebookに質問してください。

静的に型付けされた言語に関しては、今日の迅速な反復には適していません。ここに簡単な例があります。10人の開発者が継続的インテグレーションサーバーを使用して.netプロジェクトで作業しています。1人の開発者がミスを送信し、ビルド全体が壊れています。問題のある開発者が間違いを修正するために。効率的なハァッについて話しますか?型システム/静的言語はそのように相互依存しており、コードを相互依存させます。ただし、スクリプトファイルが相互依存することはありません。スクリプトの1つに問題があり、生成が停止しない場合、発生する問題はすべてランタイムに委ねられます。そして、ランタイムは決して止まりません。壊れることはありません。誤った出力を生成する可能性がありますが、型システムのようにプロセス全体を停止するだけではありません。

0
user19718