動的プログラミング言語

動的プログラミング言語（英: dynamic programming language）は、コンピュータ・プログラミング言語において、一般にコンパイルなどの準備段階に済まされることが多いことを、準備時ではなく実行時に行うプログラミング言語処理系（の言語）である。本来は実装（処理系）のことを指すべきであるが、一般にその言語を指して議論されることが多い。もっぱら高水準言語が多い。動的言語（英: dynamic language）とも。例えば、型システムによる型チェックや、値の型変換、名前束縛などを、コンパイルなどの実行準備時ではなく実行時に行う。そういった「動的さ」により、コードの追加やオブジェクトや定義の拡張や型システムの変更によるプログラムの拡張、といったことが行いやすい、ということが利点とされる。これらの動作は静的な処理系でも手間はかかるがエミュレート可能である（例えばJavaのJDK/JREでも、クラスローダーを活用すれば可能である）。一方、動的言語ではそういったことが、直接的にサポートされる。 動的言語と動的型付けは同じ概念ではないし、全ての動的言語が必ずしも動的型付き言語というわけではない。たとえばSmalltalk環境の一つであるStrongtalk（英語版）やGradualtalkは動的な言語にも拘わらず静的型検査が可能となっている。しかし多くの動的言語は動的型付き言語である。 動的言語の定義は、「コンパイル」と「実行時」の区別だけでなく、「コード」と「データ」の区別も関わってくるため、非常にあいまいである。仮想機械や実行時コンパイラなど、機械語に何らかの抽象化を施し、機械語を実行時に生成する言語処理系は多い。一般に、ある言語が動的であるとは、その言語の能力を明確に表しているというよりも、動的な機能の使い易さを指しているといえる。 動的プログラミングの概念を密接な関連のある機構がいくつか存在する。それらは必ずしも動的言語として必須とは言えないが、動的言語と呼ばれるものに広く採用されているのも確かである。 eval（イーバル）とは、LISPで導入された用語であり、S式と呼ばれるデータ構造で表現される命令列を実行するプロセスを指している。今日では、eval と言えばテキストなど機械語以外のデータで表されたプログラムを実行する何らかの機構やプロセスを指す。多くの言語では（LISPとは異なり）プログラムテキストを読むこととそれを内部表現に変換すること、さらには内部表現から実際の動作に変換することを区別しないため、新たなプログラムテキストの評価はそういった言語の一般的性質である。それらの言語で、プログラムの実行プロセスが eval に他ならない場合、これをインタプリタ言語と呼ぶ。 エリック・マイヤー（英語版）とピーター・ドレイトンは、実行時に実行コードをロード可能な任意の言語は（たとえ、そのコードがDLLの機械語コードだとしても）、一種の eval 機能を備えていると言えるとした。彼らは高階関数が動的プログラミングの本質であるとし、「eval は高階関数の代用品にすぎない」とした。 動的言語では、オブジェクトシステムや型システムを実行時に変更できるのが一般的である。これはすなわち、実行時定義に従って新たなオブジェクトを生成したり、既存の型やオブジェクトの合成に基づいて新たなオブジェクトを生成することを意味する。また、継承関係や型の木構造の変更も指していて、既存の型の振る舞いも（特にメソッド呼び出しの観点で）それによって変化する。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++におけるマクロは、プログラム内の文字列を置換するサブセット的かつ静的な機能でしかない。これに対し動的言語では、マクロはコンパイラ内部へのアクセスを提供し、実行時にも完全なアクセスを提供する。従って、コードの最適化にも関わり、言語の文法や構文を変化させる能力を持っている。 APL Befunge ChucK Curl Dylan ECMAScript ActionScript DMDScript E4X JavaScript JScript Eiffel Erlang Forth Groovy HyperTalk Io LISP Scheme LOGO Lua Mathematica Oberon Objective-C Perl PHP Pike Prolog Python REBOL Ruby Smalltalk Bistro Self Slate Squeak SNOBOL SuperCard SuperCollider Tcl XOTcl TeXマクロ言語 VBScript Visual FoxPro Windows PowerShell xHarbour アセンブリ言語、C言語、C++、初期の Java、FORTRAN などは動的プログラミング言語ではない。