動的型付け言語は静的型付け言語よりも生産性が高いという主張をよく耳にしました。この主張の理由は何ですか?これは、構成上の規約、関数型プログラミングの使用、高度なプログラミングモデル、一貫した抽象化の使用など、最新の概念を備えたツールではありませんか?これらはすべて静的型付き言語でも使用できます。 (たとえばJavaでは)冗長な型宣言が不要なことが多いため、混乱が少ないことは確かですが、静的型付けの他の利点を失うことなく、型推論を使用する静的型付き言語のほとんどの型宣言を省略することもできます。そして、これらすべては、Scalaのような現代の静的型付け言語でも利用できます。
それで、動的型付けの生産性について、型モデル自体の利点であるとはどういうことですか?
明確化:私は、クイックハックよりも大規模または中規模のプロジェクトに関心があります。 :-)
私は実際にはかなり近いコールだと思います。動的型付けと静的型付けの両方に利点があります。
動的型付けの生産性が向上する理由:
静的型付けの生産性が向上する理由:
平均すると(フェンスの両側で長年の経験を積んだ後)、動的型付けは短期的には生産性が向上する可能性がありますが、最終的には、非常に優れたテストスイートとテスト規則がない限り、維持することが難しくなります。
一方、正確性の利点とツールのサポートにより、長期的には生産性が向上すると思うので、実際には静的に型付けされたアプローチ全体を好みます。
動的言語を使用すると、型付き言語を使用する場合よりも、くだらないコードをすばやく作成できます。
動的なものの巨大な山をすばやく作成したら、長期的なメンテナンスを気にすることなく、別のプロジェクトに安全に移動できます。
これは生産性の向上です:)
私は冗談ですが、「動的言語」を使用するプロジェクトに参加した後、実用的な製品が必要な場合に対処しなければならない不必要なテスト、ドキュメント、および慣習の量に怯えています。
そして、コンパイル時に捕捉できた可能性のある多くの実行時エラーの喜びで。
ああ、私はまた、メタプログラミングがあなたのコードに導入することを可能にしたそれらすべてのハックとvoodoosについて怒鳴ることを忘れていました!
したがって、生産性の向上は、生涯にわたる中規模/大規模プロジェクトの神話かもしれません。
この問題についても理論的な見方があります。静的型システムは基本的に、プログラムの型の正しさを証明できる場合にのみプログラムを受け入れる専門の定理証明者です。すべての静的型システムは、すべての可能な型修正プログラムを証明するのに十分強力な決定可能な静的型システムがないため、一部の有効なプログラムを拒否します。
静的型チェッカーで証明できないプログラムはハックや悪いスタイルであると主張する人もいますが、すでに有効なプログラムを入手していて、型チェッカーがそれを受け入れない場合、短期的には生産性が損なわれます。
タイプチェッカーが邪魔になっていることに気づくかもしれないいくつかのケースは、一般的なコンテナーと、引数と戻り値の型の共/反変です。
ほとんどの動的言語で私が見つけた利点の1つは、より一般的なコードを簡単に記述できることです。型システムと戦う必要がない場合は、より高い抽象化レベルで書く方がはるかに簡単です。
あなたはそれについてそれほど考える必要はありません-Java内のanyオブジェクトで重要でない何かを行うコードを書くことは困難であり、おそらく基本的に動的なリフレクションを必要とします型付き; JavaScriptのようなもので、すべてのオブジェクトに対して何か面白いことをする関数を書くことは第二の性質です。完璧な例は、私が最近書いた関数で、オブジェクトを取り、そのすべてのメソッドを同じことをするだけのメソッドで置き換えますイベントを発生させます。Javaでこのような方法に取り組む方法はわかりませんが、これがどれだけ型システムによるもので、他の言語の違いによるものなのかはわかりません。
しかし、最近Haskellを使い始めました。 Haskellを使用すると、私が使用した動的に型付けされた言語と同じくらい簡単に、抽象的な汎用コードを書くことができます。上記の私のJava/JavaScriptの例は、Haskellではnoに意味があります。オブジェクト、メソッド、イベント、さらには多くの変更がないためですが、他の種類の汎用コードは本当に簡単に書くことができます。
実際、Haskellは動的に型付けされた言語ではできないいくつかの一般的なコードを書くことができます。完璧な例はread
関数です。これは基本的にtoString
の反対です。 Int
やDouble
などの任意の型を取得できます(特定の型クラスに属している場合)。多態性定数を使用することもできるため、maxBound
は最大のInt
、Double
、Char
...などにすることができます。 、すべてのタイプに応じて異なります。
私の理論では、動的言語を使用することによる生産性の向上は、Javaのような言語と比べると、機能が少なく、冗長で、柔軟性が低い型システムです)。
ただし、Haskellの型システムでさえ、動的に型付けされた言語にはないような厄介な問題があります。私が悩んでいる最大の問題は、数値の処理方法です。たとえば、(リストの)length
をdoubleとして使用するには、型システムをいじる必要があります。型システムがなくても問題はありません。私が遭遇したもう1つの迷惑なことは、Word8
(unsigned int型)およびInt
を期待する関数。
したがって、最終的には、型システムがないことで、あまり考えずに一般的なコードを簡単に記述できるようになり、型システムの落とし穴を回避することもできます。動的言語で型システムと戦う必要はありませんが、それに頼ることはできません。
Q:動的に型付けされた言語は静的に型付けされた言語よりも生産性が高いという主張をよく耳にしました。この主張の理由は何ですか? "
これには歴史的な理由があります。数十年前に戻ると、動的言語は静的言語よりも明らかに生産性が高かった(同時に大幅に遅い)。 Perlは、両方を知っていて、手元のタスクがどちらかを許可している場合、Cよりも明らかに生産性が高くなります。しかし、時間の経過とともに言語は相互に多くを借用し、新しい言語は(生産性とパフォーマンスの両方で)ギャップを狭めています。
考慮すべきいくつかのポイントを次に示します。
ガベージコレクション:ガベージコレクションは巨大な生産性の向上です。 Javaは、GCを使用した最初の主流の静的言語でした。これ以前は、静的は基本的に手動によるメモリ管理を意味していました。(注:以下では、主流の言語のみを検討しています。多くの実験的なそして、ニッチな言語が存在し、私が作るあらゆる点に反例を提供します。
メモリの安全性:足元で自分を撃つことを心配する必要がない生産性の向上です。 Javaのような「管理された」静的言語の前は、静的とは通常、直接メモリアクセスを意味していました。デバッグも生産性の一部であり、安全でないメモリアクセスは本当にあいまいなバグにつながる可能性があります。
面倒な型システム。静的言語でパラメーター化された型(テンプレートやジェネリックなど)が導入される前は、静的型システムの制限がしばしば負担でした。たとえば、Javaでは、コレクションからアイテムを選択するたびに明示的にダウンキャストする必要がありました。そのため、キャストの構文オーバーヘッドと型安全性なし。プログラミングにおけるユビキタスコレクションの存在を考えると、これは大きな欠点でした。
すべての型を宣言することは冗長な型付けの多くですが、現代の型推論では、これを大幅に減らすことができます。
大きな標準ライブラリ。 Pythonは、大きな標準ライブラリのため、「バッテリーが含まれている」と宣伝されたことが有名です。これは、非常にミニマリストな標準ライブラリを持つCと比較してです。しかし、 Javaおよび.netのようなプラットフォームでは、広大な標準ライブラリが標準になりつつあり、ScalaおよびF#のような新しい言語はこれを「無料」で継承しています。
ファーストクラスのデータ構造 PerlやPythonなどの動的言語には、リストやマップなどの組み込みのファーストクラスのデータ構造があり、一般的な操作に便利な構文ショートカットが用意されています。これには、Cには固定サイズの配列以外の組み込みのコレクションはありません。
Closures and lambda syntax-通常、動的言語は最初からこれを採用していましたが、静的言語はこれを採用し、最近ではJavaを採用しています。
[〜#〜] repl [〜#〜]インタラクティブにコードスニペットをすばやくテストする機能は大きな恩恵です。しかし、IDEツール、たとえばVisual Studioの「イミディエイト」ウィンドウのように、静的言語はこれをある程度エミュレートできます。
高度なツール-静的言語が動的言語の利便性に近づいている上記の点に加えて、現代のエディターは動的分析が困難な方法でマッチングするように静的分析を利用しています。たとえば、編集者は安全な自動リファクタリングを提供できますが、これは動的言語では厳密には不可能です。
結論:歴史的にはそれは真実でしたが、今日の答えはそれほど明確ではありません。
Q:それで、動的型付けの生産性に関して、型モデル自体の利点であると言えるものは何ですか?
動的型付けモデルを動的言語から分離するのは少し難しいですが、例として、C#は静的言語であるため、C#は時間とともにより動的な機能を採用しています。これは、動的型モデルの利点の証明です。例:
Reflectionリフレクションは基本的に動的なタイピング機能です。コンパイル時ではなく実行時評価者でオブジェクトタイプを検査します。それが導入されたとき、それは一種の眉をひそめましたが、C#ではリフレクションの使用はますますユビキタスになり、たとえばASP.Net MVCはリフレクションを頻繁に使用します。
Attributes属性は動的型付けの例です。コンパイル時に任意の属性をクラスに追加し、実行時に(リフレクションを介して)検査し、それに基づいてオブジェクトを操作できます。 MEPのようなものは、基本的には動的型モデルに基づく拡張フレームワークです。
Linq to SQL、EF mv。さまざまなLinqトランスフォーマーは、実行時オブジェクトとしてクエリを検査し、オンザフライでsqlを生成します。実行時にコードを検査するよりも動的にはなりません。 CodeDomはコインの反対側であり、実行時にコードを生成できます
Roslyn Roslynは基本的にeval
を実装します。これはかつて真に動的な言語の定義機能と見なされていました。
動的dynamic
- typeは、C#で最も明示的に動的な機能であり、外部オブジェクトや言語との相互作用をよりシンプルかつ生産的にすることで宣伝されています。ただし、便宜上、Asp.net MVCでも使用されます。
上記のすべての機能の利点は、パラメーター化された型、構造型、および型推論を持つ静的言語において、動的モデルに明確な利点evenがあることを示しています。
現代の言語機能はすべて非常に大きいため、静的型付けと動的型付けだけではそれほど重要ではありません。
ルールは、言語機能が優れているほど、コードが短くなることです。とても簡単です。 Javaは、静的型付けがひどくうまくいかない可能性があることを示しています。不十分に設計された言語機能は一般にコストがかかります。Javaでの静的型付けは、最初は必須の機能であり(そうでなければほとんどの人はおそらくそれを使用しないでしょう)、次に不十分に実行されます。
これが、多くの理由により、PHPが(少なくとも最近まで)総計であなたの人生を本当に良くするとは言えないとしても、ほとんどの動的言語が優れている理由です。型システムに関係のないその他の癖。
一方で、あなたは邪魔にならず、必須ではない表現型システムを備えた多くの言語を持っています。また、型システムをエスケープする必要がある場合は常に、型なしのコードを埋め込むこともできます。
個人的に、私は型推論、名義型と構造型の両方のサブタイプ、オプションの型なしコード、ファーストクラスの関数型、代数的データ型、および(かなり成熟してはいないが非常に強力な)字句マクロを備えた言語であるhaXeを使用していますが、その間、難解な構文を回避しています。 haXeを約3年間使用した後、簡単な結論に達しました。
あなたの言語がパラダイムについての宗教的な選択にあなたを縛り付けないが、ただ良いツールであるように試みるとき、プログラミングははるかに簡単になります。多くの静的言語と動的言語および混合言語があり、そこで成功しています。それらのいくつかは習得が簡単で、習得が最も困難です。
それらの力は、個々の機能を構成して複雑な問題の簡単な解決策を簡単に作成できる方法に由来しています。これは、これまでに検討されたすべての言語機能の包含または省略の微妙なバランスによってのみ達成できる特定の直交性を排除します。 Rubyに静的型付けを追加しようとすると、それが機能しなくなり、Haskellからそれを削除しようとすると、クラッシュします。それとは対照的に、あなたがCからそれを奪った場合、人々はほとんど気付かず、Javaからそれを奪った場合、一部はあなたに感謝するかもしれません。
私の個人的な経験から、私はこれをあなたに言うことができます:私はRubyが好きです。それは私の視野と私がシステムを設計する方法を広げました。私見それはそもそも人々にプログラミングを教えるために使われるべきです。それは控えめで、強力で、簡潔で、楽しいです。なぜ正統派言語から来た人がそれを楽しむのか理解しています。
ただし、長期的には、静的型付けは静的アナライザーに作業を延期することを許可し、型推論によりこれは基本的に無料で行われます。その結果、コードの保守が容易になり、実行速度が向上することがよくあります。
しかし、繰り返しになりますが、静的型付けだけでは何もできません。それは組み合わせの問題です。 F#、Scala、Nemerle、OCaml、haXeの間のどこかで、あなた自身の最適を見つけることができると思います。しかし、それは最終的にはあなた次第です。言語は、思考を曲げることを強いるのではなく、努力なしに思考を埋め込むことができるからです。そして結局のところ、プログラミングが楽しい場合ほど、生産性を向上させるものはありません。
個人的には、動的タイピングが役立つ唯一の理由は、あなたが本当にタイピストであるか、ナビゲートしにくい巨大な関数/メソッド/何かを構築している場合です。また、ユニットテスト全体の問題にも取り組む必要があります。動的な型には、(壊れたコードを書くのが好きでない限り)強力な単体テストが必要です(動的な型が予期せず爆発しないようにするために(つまり、変数がほとんどダックになっているが、偶然にdcukがときどき))。 Staticsはこれを防ぐためにより多くの努力をします(そして、はい、あなたは活発なユニットテストの議論をすることができます)
まず、「生産性」を定義する必要があると思います。 「生産性」とはどういう意味ですか?
「より生産的」とは、同じ機能を実装するためのコード行を少なく書くことを意味するのであれば、そうです、動的型付けプログラミング言語は静的型付け言語よりも「生産的」です。
ただし、デバッグとバグ修正に費やす時間も考慮すると、動的型付け言語はそれほど生産的ではない可能性があります。動的型付け言語は、静的型付け言語とは対照的に、エラーチェックをランタイムにプッシュする傾向があるためです。コンパイル時にエラーチェックを実行できます。一般的に認められているように、通常、バグが後から発見されるほど、そのバグを修正するのにコストがかかります。したがって、動的型付けコードは、静的型付けコードよりも生産性が一般的に同等か、場合によってはそれよりも低くなる可能性があります。