動的プログラミング言語
動的プログラミング言語(どうてきプログラミングげんご、英: dynamic programming language)は、コンピュータ・プログラミング言語において、一般にコンパイルなどの準備段階に済まされることが多いことを、準備時ではなく実行時に行うプログラミング言語処理系(の言語)である。本来は実装(処理系)のことを指すべきであるが、一般にその言語を指して議論されることが多い。もっぱら高水準言語が多い。動的言語(英: dynamic language)とも。例えば、型システムによる型チェックや、値の型変換、名前束縛などを、コンパイルなどの実行準備時ではなく実行時に行う。そういった「動的さ」により、コードの追加やオブジェクトや定義の拡張や型システムの変更によるプログラムの拡張、といったことが行いやすい、ということが利点とされる。これらの動作は静的な処理系でも手間はかかるがエミュレート可能である(例えばJavaのJDK/JREでも、クラスローダーを活用すれば可能である)。一方、動的言語ではそういったことが、直接的にサポートされる。
動的言語と動的型付けは同じ概念ではないし、全ての動的言語が必ずしも動的型付き言語というわけではない。たとえばSmalltalk環境の一つであるStrongtalkやGradualtalkは動的な言語にも拘わらず静的型検査が可能となっている。しかし多くの動的言語は動的型付き言語である。
定義の限界と曖昧さ
[編集]動的言語の定義は、「コンパイル」と「実行時」の区別だけでなく、「コード」と「データ」の区別も関わってくるため、非常にあいまいである。仮想機械や実行時コンパイラなど、機械語に何らかの抽象化を施し、機械語を実行時に生成する言語処理系は多い。一般に、ある言語が動的であるとは、その言語の能力を明確に表しているというよりも、動的な機能の使い易さを指しているといえる。
実装
[編集]動的プログラミングの概念を密接な関連のある機構がいくつか存在する。それらは必ずしも動的言語として必須とは言えないが、動的言語と呼ばれるものに広く採用されているのも確かである。
eval
[編集]高階関数
[編集]エリック・マイヤーとピーター・ドレイトンは、実行時に実行コードをロード可能な任意の言語は(たとえ、そのコードがDLLの機械語コードだとしても)、一種の eval 機能を備えていると言えるとした。彼らは高階関数が動的プログラミングの本質であるとし、「eval は高階関数の代用品にすぎない」とした[1]。
オブジェクトシステムや型システムの実行時変更
[編集]動的言語では、オブジェクトシステムや型システムを実行時に変更できるのが一般的である。これはすなわち、実行時定義に従って新たなオブジェクトを生成したり、既存の型やオブジェクトの合成に基づいて新たなオブジェクトを生成することを意味する。また、継承関係や型の木構造の変更も指していて、既存の型の振る舞いも(特にメソッド呼び出しの観点で)それによって変化する。Smalltalkのクラス登録などが顕著な例である。
Object
subclass: #Some
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Example'.
上記はクラス定義用の専用構文ではなく、Objectというクラスオブジェクトにクラス登録用のメッセージを送っているだけである。実行中に登録しているが削除も実行中に可能である。
制御構文
[編集]LispやSmalltalkをはじめ幾つかの言語は分岐や反復の専用の制御構文を持たない。無名関数と高階関数の組み合わせによって全てを代用している。
[
Error signal: '処理失敗'.
]
on: Exception
do:
[ :exception |
"例外を捕捉"
].
上記はSmalltallkによる例外処理の例である。クラス登録と同じく言語機能による専用構文ではない。
メッセージ送信
[編集]Smalltalk系統のオブジェクト指向言語にみられる。一つのメソッドに複数セレクターと紐づけたり、全てのメッセージを受け取るメソッドを定義することで、メッセージを受信するオブジェクトがメッセージと同じセレクターを持つメソッドを備えていなくてもメッセージを受信できる。
"#onClick:を使ったメッセージをopen:メソッドに転送させる。"
FileEventHandler
addSelector: #onClick:
withMethod: FileEventHandler >> #open:.
上記はSmalltalkで既に#open:というセレクターを持っているメソッドに#onClick:というセレクターを追加している。
「メッセージ転送」も参照のこと。
関数型プログラミング
[編集]関数型プログラミングの概念は多くの動的言語に備わっている。これも LISP を起源としている。
継続
[編集]動的言語における別の機能として継続がある。継続は、再呼び出し可能な実行状態を表している。例えば、構文解析器が中間結果と継続を返し、後で再呼び出しされると、入力の構文解析を再開する。継続はクロージャなどのスコープと複雑に関連している。このため、継続を提供している動的言語は多くはない。
イントロスペクション
[編集]イントロスペクションは多くの動的言語で見られ、自分自身の構造・コード・型・データなどを解析するプログラムによく使われる。これは総称型やポリモーフィズムの値について型を決定するのと似たようなものである。プログラムのコードをデータとして完全に解析可能な場合もあり、例えば LISP ではプログラムをS式として解析可能である。
マクロ
[編集]動的プログラミング言語の中には、コードのイントロスペクションと eval 機能を組み合わせてマクロと呼ばれる機能を提供するものもある。C言語やC++におけるマクロは、プログラム内の文字列を置換するサブセット的かつ静的な機能でしかない。これに対し動的言語では、マクロはコンパイラ内部へのアクセスを提供し、実行時にも完全なアクセスを提供する。従って、コードの最適化にも関わり、言語の文法や構文を変化させる能力を持っている。
言語
[編集]アセンブリ言語、C言語、C++、初期の Java、FORTRAN などは動的プログラミング言語ではない。
出典
[編集]- ^ Meijer, Erik and Peter Drayton (2005年). “Static Typing Where Possible, Dynamic Typing When Needed: The End of the Cold War Between Programming Languages”. Microsoft Corporation. 2008年1月18日閲覧。
外部リンク
[編集]- Dynamic Languages[リンク切れ] by David Ascher.