私は Java の世界から来ましたが、コードのコンパイル中にエラーが発生しないこと以外に、Python の動的型付けの優れた点は何でしょうか?
Python のタイピングは好きですか? 大きなプロジェクトで役に立った例はありますか? ちょっとミスしやすいんじゃない?
私は Java の世界から来ましたが、コードのコンパイル中にエラーが発生しないこと以外に、Python の動的型付けの優れた点は何でしょうか?
Python のタイピングは好きですか? 大きなプロジェクトで役に立った例はありますか? ちょっとミスしやすいんじゃない?
一般的なケースでは、静的型チェックは決定できません。これは、静的にタイプ セーフであるが、タイプ チェッカーが静的にタイプ セーフであることを証明できないプログラムが存在することを意味します。したがって、タイプ チェッカーはそれらのプログラムを拒否する必要があります。
言い換えれば、タイプチェッカーが作成を許可しないタイプセーフなプログラムがあります。または、もっと簡潔に言うと、静的型付けは、特定のプログラムを作成することを妨げます。
これは、Java だけでなく、すべての静的型付け全般に当てはまります。
特にJavaに関しては、かなりくだらない型システムを持っています。その型システムは、非常に単純なプロパティでさえ表現できるほど表現力がありません。例: の型のどこでstatic void java.util.Arrays.sort(Object[] a)
、結果をソートする必要があると実際に言っているのでしょうか? または、配列要素を部分的に順序付けする必要がありますか?
Java のもう 1 つの問題は、型システムにトラックが通れるほど大きな穴があることです。
String[] a = new String[1];
Object[] b = a;
b[0] = 1; // ArrayStoreException
この特定のケースの問題は、共変配列です。配列が共変かつ型安全であることは単純に不可能です。
Java は、静的型付けの煩わしさをすべて兼ね備えていますが、利点はありません。だから、あなたは面倒を取り除くこともできます。
ただし、これは普遍的ではないことに注意してください。トレードオフがあまり明確でない、はるかに優れた型システムを持つ他の言語があります。
たとえば、これは Python で史上最も愚かな言語ベンチマーク (フィボナッチ) です。
def fib(n):
if n < 2: return n
return fib(n-2) + fib(n-1)
および Java:
int fib(int n) {
if (n < 2) return n;
return fib(n-2) + fib(n-1);
}
そこには、静的型付けにのみ関連するかなりの混乱があることに注意してください。比較をより公平にするために、Python の構文と Java のセマンティクスを持つ言語を想像してみましょう。
def fib(n: int) -> int:
if n < 2: return n
return fib(n-2) + fib(n-1)
[興味深い補足: Python 3.x でオプションの静的型注釈が追加されたことにより、これは実際には有効な Python コードでもありますが、注釈は単なる注釈であるため、静的に型安全ではないことは明らかです。実際にはどこでもチェックされることはありません。]
そこには明確な混乱があります。ただし、Haskell では次のようになります。
fib n
| n < 2 = n
| otherwise = fib (n-2) + fib (n-1)
Python バージョンとは異なり、これは完全に静的にタイプ セーフですが、タイプ関連の混乱はありません。
この特定のケースでは、静的型付けと動的型付けの利点の間の問題はあまり明確ではありません。
ちなみに、より慣用的な Haskell バージョンは、おそらく次のようになります。
fib 0 = 0
fib 1 = 1
fib n = fib (n-2) + fib (n-1)
またはこれ:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
実際、Java と Python のより重要な違いは、Java が静的に型付けされ、Python が動的に型付けされるということではなく、Java が優れたプログラミング言語ではないのに対し、Pythonは. つまり、Java は静的に型付けされているからではなく、がらくただから常に負けるのです。BASIC と Haskell を比較すると、Haskell が明らかに勝っていますが、静的に型付けされているからではなく、BASIC がくだらないからです。
より興味深い比較は、Java と BASIC、または Python と Haskell です。
自明ではないJavaプログラムの大部分には、動的型付けが含まれていると思います。
Javaでオブジェクトから明示的な型へのキャストを行うたびに、動的型チェックを行っています。これには、ジェネリックが1.5で導入される前のコレクションクラスのすべての使用が含まれます。実際、Javaジェネリックは、実行時まで一部の型チェックを延期することができます。
Javaリフレクションを使用するたびに、動的型チェックを実行します。これには、テキストファイル内のクラスまたはメソッド名から実際のクラスまたはメソッドへのマッピングが含まれます。たとえば、SpringXML構成ファイルを使用するたびに。
これにより、Javaプログラムは脆弱になり、エラーが発生しやすくなりますか?Javaプログラマーは、時間のかなりの部分を、誤った動的型付けの問題を追跡して修正するために費やしていますか?おそらくそうではありません-そしてPythonプログラマーもそうではありません。
動的型付けの利点のいくつか:
Pythonでそれが好きですか?
これは Pythonの一部です。Pythonでそれを好むのはばかげています。
大きなプロジェクトで役に立った例はありますか?
はい。毎日、私は変更を加えることができることを喜んでいます。また、Duck のタイピングのおかげで、それらは適度にローカライズされ、すべての単体テストに合格し、すべての統合テストに合格し、他の場所で中断されるものは何もありません。
これが Java の場合、Java の静的型チェックでまだ許可されているバリエーションを導入できるように、クラスからインターフェイスを引き出すには、無限のリファクタリングが必要になります。
少しエラーが発生しませんか?
静的型付けにすぎません。簡単な単体テストで、オブジェクトが期待される機能に準拠していることを確認します。
(a) コンパイル時のチェックに合格し、(b) 実行時にひどくクラッシュするクラスを Java で作成するのは簡単です。キャストはこれを行う良い方法です。クラスの意図を満たさないことはよくあることです。クラスはコンパイルできても動作しません。
多くのパターン(GoFなど)は不要であるか、機能的なフレーバーを備えた動的型付け言語でより少ない労力で実装できます。実際、多くのパターンがpythonに「組み込まれている」ので、短くて「pythonic」なコードを書くと、すべての利点を無料で得ることができます。Iterator、Observer、Strategy、Factory Method、Abstract Factory、およびJavaやC++で一般的なその他のパターンは必要ありません。
これは、書くコードが少なくなり、(はるかに重要な)読み取り、理解、サポートするコードが少なくなることを意味します。これがPythonのような言語の主な利点だと思います。そして私の意見では、これは静的型付けがないことをはるかに上回っています。タイプ関連のエラーはPythonコードではあまり発生せず、単純な機能テストで簡単にキャッチできます(このようなテストは、JavaよりもPythonで作成する方が確実です)。
あなたが Java の世界の出身であるため、Java の型システムを満足させるためだけに、書かなければならないものをすべて書かなくてもよいのは素晴らしいことだというのが明白な答えです。
もちろん、静的に型チェックされた言語は他にもありますが、Java で書かなければならないすべてのものを書く必要はありません。
C# でさえ、ローカル メソッド変数の型推論を行います!
また、Java が提供するよりも多くのコンパイル時エラー チェックを提供する、静的に型チェックされた言語が他にもあります。
(Python の動的型付けの何がそんなに優れているのか? に対するあまり明白でない答えを理解するには、おそらく Python をもっと理解する必要があります。)
それはあなたの心の負荷です。赤の色は、"Red" (定数) として "255, 0, 0" (タプル) または "#FF0000" (文字列) と考えることができます: 3 つの異なる形式で、3 つの異なる型または複雑なルックアップが必要になります。および Java の変換メソッド。
コードが簡単になります。
たとえば、整数だけでなく、文字列、リスト、辞書などを渡すことができる関数を作成でき、それらすべてを適切な方法で透過的に処理できます (または例外がスローされる場合)。タイプを処理できません)。他の言語でもそのようなことを行うことができますが、通常、ポインター、参照、型キャストなどを (ab) 使用する必要があり、プログラミング エラーの穴が開いてしまいます。