原文:http://python-history.blogspot.com/2009/02/pythons-use-of-dynamic-typing.html
原文投稿者:Guido van Rossum
ABCとPythonが大きく異なるのは、型システムに対する基本的な姿勢である。ABCは静的な型付けを採用している。ABCコンパイラは常にプログラムの中の型の使われ方を分析し、どのように使用されているのか分析を行う。もしうまく分析できないときは、そのプログラムは拒絶され、処理が実行されることはない。 当時の他の静的な型を持つ言語とは異なり、C言語のように明示的な型宣言をさせる代わりに、ABCは型推論を行っていた。ただし、Haskellとは似てなかった。それとは対照的に、Pythonでは動的な型システムを採用している。Pythonコンパイラは、型がどのようにプログラムの中で使用されるかという点には無関心である。型のチェックはすべて実行時に行われるのである。
これはABCから遠く離れた仕様のように見えるかもしれないが、読者の方々が思ったほどの違いはない。他の静的な型を持つ言語とは異なり、ABCは静的な型チェックだけに頼って、プログラムをクラッシュから守ろうとしているわけではないからだ(<-現在からすると歴史的なことなので過去形を使ったほうがよかったかも:-)。ランタイムライブラリは実行されるたびに、引数の型がどのように操作できるかというチェックをすべて行っていた。これはコンパイラと同じ型チェックアルゴリズムを使い、健全かどうかのチェックの一部として行われていたのである。初期の言語実装の中では、このチェックアルゴリズムの完全な実装は行われていなかった。ランタイムライブラリが明示的に実行時の型チェックを行い、わかりやすいエラーメッセージを出してくれたため、ライブラリ自体がデバッグを手助けしてくれたのである。この機能は実装チーム向けに整備された。そのため、引数を間違って指定したために、未チェックの何かの操作が行われて、インタプリタがどこかに行ってしまってコアダンプする、ということは起きなかったのである。
しかし、ABCが静的な型のチェックに加えて、実行時にも型のチェックを行っていた本当の理由は別にある。それはABCがインタラクティブな実行を許容していたからである。インタラクティブなセッションの中では、ユーザがABCの文や宣言を入力し、入力が完了したらその場で実行される。インタラクティブセッションでは、数値型として変数を作ったり、それを消したり、文字列型として再作成(言い方を変えると、別の変数を同じ名前で作成)したり、といったことが可能であった。一連の手続きの中で再作成した場合には、最初に数値型で変数を作成し、その次に同名の変数を文字列型として作成すると、静的な型エラーが検知されることが期待されるだろう。しかしインタラクティブセッションの中では、文を越えて型チェックを強制させられて、再作成が禁止されてしまうと都合が悪いことがある。もし間違って変数xを数値型で作ってしまうと、変数xを別の型で作成することができなくなってしまうからである。双方を考慮して妥協した結果、ABCはグローバル変数のチェックには動的な型チェックを使用するが、ローカル変数に対しては静的な型チェックを使用するというところに落ち着いた。Pythonではこれをさらにシンプルに実装して、ローカル変数に対しても動的な型チェックを行うようにしたのである。
そのため、Pythonの型チェックのアプローチと、ABCが実装したアプローチは、実際にはそれほど大きな差はないのである。Pythonはシンプルに、コンパイル時の型チェックを完全になくした。型に関するすべてのエラーは実行時に捕まえられるため、Pythonインタプリタが動作停止させられることはない。実行時だけのチェックであっても、最終的な動作の安全には悪い影響を与えることはないのである。これはPythonの「うまく手を抜く」という設計哲学にきちんと合っていると言えるだろう。
しかし、一度でも動的な型システムを使おうとすると、もう戻ることはできなくなってしまうだろう。ABCの組み込みの演算子は、演算の形式を見て型を推測できるように、慎重に設計されていた。例えば、ABCのコンパイラは、"x ^ y"という形の式から、コンパイラは変数xとyは文字列であり、演算結果も同様に文字列であるということを推測を行う。Pythonではもはやこのような推測を、一般化して実装することは不可能である。例えば、"x + y"という式は文字列の結合にも使用できるし、数値の足し算にも使用できる。また、Pythonでは、自分で定義した型に対して、自分でオーバーロードして演算子の動作を書き換えることもできるからである。
0 件のコメント:
コメントを投稿