CommonLispオブジェクトシステム

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ
ANSI CommonLispでの標準的なメソッドの組み合わせ

Common Lisp Object System(CLOS)は、ANSI CommonLisp一部であるオブジェクト指向プログラミングのための機能ですCLOSは強力な動的オブジェクトシステムであり、 C ++Javaなどのより静的な言語に見られるOOP機能とは根本的に異なりますCLOSは、 MITフレーバーCommonLoopsなどの初期のLispオブジェクトシステムに触発されましたが、どちらよりも一般的です。もともとアドオンとして提案されたCLOSは、Common LispのANSI標準の一部として採用され、EuLispやEmacsLispなどの他のLisp方言に採用されました。 [1]

機能

CLOSの基本的な構成要素は、メソッドクラス、それらのクラスのインスタンス、およびジェネリック関数です。defclassCLOSは、、、、defmethodおよびを定義するマクロを提供しますdefgenericインスタンスはメソッドで作成されmake-instanceます。

クラスには、複数のスーパークラス、スロットのリスト(C ++ / Java用語ではメンバー変数)、および特別なメタクラスを含めることができます。スロットは、クラス(クラスのすべてのインスタンスがスロットを共有する)またはインスタンスごとに割り当てることができます。各スロットには名前があり、関数を使用してその名前でスロットの値にアクセスできますslot-valueさらに、スロットの値を読み書きするための特別な汎用関数を定義できます。CLOSクラスの各スロットには、一意の名前を付ける必要があります。

CLOSは多重ディスパッチシステムです。これは、メソッドが必要な引数のいずれかまたはすべてに特化できることを意味します。ほとんどのオブジェクト指向言語はシングルディスパッチです。つまり、メソッドは最初の引数にのみ特化しています。もう1つの珍しい機能は、メソッドがクラスに「属さない」ことです。クラスは、ジェネリック関数またはメソッドの名前空間を提供しません。メソッドはクラスとは別に定義され、クラススロットへの特別なアクセス(「this」、「self」、「protected」など)はありません。

CLOSのメソッドは、ジェネリック関数にグループ化されています。ジェネリック関数は、関数のように呼び出すことができ、メソッドのコレクションを、それぞれが異なる引数に特化した共有名と引数構造に関連付けるオブジェクトです。Common Lispは構造体と組み込みデータ型(数値、文字列、文字、記号など)に非CLOSクラスを提供するため、CLOSディスパッチはこれらの非CLOSクラスでも機能します。CLOSは、個々のオブジェクト(eqlスペシャライザー)へのディスパッチもサポートします。CLOSは、デフォルトでは、すべてのCommon Lispデータ型に対するディスパッチをサポートしていません(たとえば、ディスパッチは、完全に特殊化された配列型またはによって導入された型に対しては機能しませんdeftype)。ただし、ほとんどのCommonLisp実装はメタオブジェクトプロトコルを提供しますこれにより、ジェネリック関数がアプリケーション固有の特殊化およびディスパッチルールを提供できるようになります。

CLOSでのディスパッチも、ほとんどのOO言語とは異なります。

  1. 引数のリストが与えられると、適用可能なメソッドのリストが決定されます。
  2. このリストは、パラメータースペシャライザーの特異性に従ってソートされています。
  3. このリストから選択されたメソッドは、ジェネリック関数で使用されるメソッドの組み合わせを使用して、効果的なメソッドに結合されます。
  4. 次に、元の引数を使用して有効なメソッドが呼び出されます。

このディスパッチメカニズムは実行時に機能します。したがって、メソッドを追加または削除すると、実行時に有効なメソッドが変更される可能性があります(ジェネリック関数が同じ引数で呼び出された場合でも)。メソッドの組み合わせを変更すると、効果的なメソッドが異なる場合があります。

例えば、

; 共通引数構造のプロトタイプを宣言します
defgeneric  f  x  y ))

; (f integer t)の実装を定義します。ここで、tはすべてのタイプに一致します
defmethod  f  ((x  integer  y  1 

f  1  2.0  =>  1

; (f integer real)
defmethod  f  ((x  integer  y  real )) 2 )の実装を定義します

f  1  2.0  =>  2  ; 実行時にディスパッチが変更されました

ほとんどの動的言語のオブジェクト指向システムと同様に、CLOSはカプセル化を強制しませんslot-value関数を使用するか、(オプションで自動生成された)アクセサメソッドを介して、任意のスロットにアクセスできます経由でアクセスするにslot-valueは、スロットの名前を知っている必要があります。CLプログラマーは、言語のパッケージ機能を使用して、エクスポートする関数またはデータ構造を宣言します。

通常の(「プライマリ」)メソッドとは別に、、、および「補助」メソッドも:beforeあり:afterます:around前の2つは、クラス階層に基づいた特定の順序で、プライマリメソッドの前または後に呼び出されます。:aroundメソッドは、プライマリメソッドを実行するかどうかを制御できますさらに、プログラマーは、クラス階層に沿って可能なすべてのプライマリメソッドを呼び出すか、最も近いものだけを呼び出すかを指定できます。

標準メソッド-組み合わせは、上記で説明したメソッドの前、後、および周辺の主要なメソッドを提供します。他のメソッド-他のメソッドタイプとの組み合わせがあります。新しい(単純なものと複雑なものの両方)メソッド-組み合わせとメソッドタイプを定義できます。

CLOSは多重継承を許可します。メソッドが多重継承で実行されるデフォルトの順序が正しくない場合、プログラマーはメソッドの組み合わせの順序を指定すること でダイヤモンド継承の問題を解決できます。

CLOSは動的です。つまり、コンテンツだけでなく、そのオブジェクトの構造も実行時に変更できます。CLOSは、クラス定義をオンザフライで変更すること(問題のクラスのインスタンスがすでに存在する場合でも)、およびchange-class演算子を介して特定のインスタンスのクラスメンバーシップを変更することをサポートします。CLOSを使用すると、実行時にメソッドを追加、再定義、および削除することもできます。円-楕円問題CLOSで簡単に解決でき、ほとんどのOOPデザインパターンは消えるか、質的に単純になります。[2]

CLOSはプロトタイプ言語ではありません。オブジェクトをそのクラスのメンバーとしてインスタンス化する前に、クラスを定義する必要があります。

メタオブジェクトプロトコル

ANSI Common Lisp標準の外に、メタオブジェクトプロトコル(MOP)と呼ばれるCLOSへの広く実装された拡張機能があります。MOPは、CLOS実装の基盤への標準インターフェイスを定義し、クラス、スロット記述、総称関数、およびメソッド自体をメタクラスのインスタンスとして扱い、新しいメタクラスの定義とすべてのCLOS動作の変更を可能にします。CLOS MOPの柔軟性は、アスペクト指向プログラミングを予見します。アスペクト指向プログラミングは、後にGregorKiczalesなどの同じエンジニアによって開発されました。MOPは、一連のプロトコルによってオブジェクトシステム全体の動作を定義します。これらはCLOSの観点から定義されています。したがって、提供されているCLOS機能を拡張または変更することにより、新しいオブジェクトシステムを作成することができます。The Art of the Metaobject Protocol 』では、CLOSMOPの使用と実装について説明しています。

さまざまなCommonLisp実装では、メタオブジェクトプロトコルのサポートがわずかに異なります。Closer [3]プロジェクトは、不足している機能を提供することを目的としています。

古いLispベースのオブジェクトシステムからの影響

フレーバー(およびその後継のニューフレーバー)は、MIT LispMachineのオブジェクトシステムでした。Lisp Machineオペレーティングシステムの大部分とそのための多くのアプリケーションは、フレーバーまたは新しいフレーバーを使用します。フレーバーは、他の機能の中でも、多重継承ミックスインを導入しました。Common Lispの実装は存在しますが、フレーバーはほとんど廃止されています。フレーバーはメッセージパッシングパラダイムを使用していました。新しいフレーバーはジェネリック関数を導入しました。

CommonLoopsはLOOPSの後継でした(Xerox Interlisp -Dから)。CommonLoopsはCommonLispに実装されました。Portable CommonLoops(PCL)と呼ばれるポータブル実装は、CLOSの最初の実装でした。PCLは広く移植されており、いくつかのCommonLisp実装のCLOS実装の基盤を提供していますPCLは、ほとんどの場合、システムに依存する部分が少ないポータブルCommonLispに実装されています。

他のプログラミング言語のCLOS

CLOSのパワーと表現度、およびTinyCLOS(Schemeで使用するためにGregor Kiczalesによって作成された簡略化されたポータブルCLOS実装)の歴史的な可用性により、CLOSのようなMOPベースのオブジェクトシステムはほとんどのLispで事実上の標準になっています方言の実装、および他のいくつかの言語のOOP機能への道を見つける:

さらに読む

  • CommonLoops:Lispとオブジェクト指向プログラミングのマージ」、Daniel G. Bobrow、Kenneth Kahn、Gregor Kiczales、Larry Masinter、Mark Stefik、FrankZdybelによる。1986年、米国オレゴン州ポートランド。オブジェクト指向プログラミングシステムの言語とアプリケーションに関する会議、ISSN 0362-1340の17〜29ページ
  • 「CLOSの歴史と説明」、JimVeitch著。プログラミング言語ハンドブック、第IV巻:関数型および論理プログラミング言語、ed。の107〜158ページ。ピーターH.サルス1998年(初版)、マクミランテクニカルパブリッシング; ISBN  1-57870-011-6

参考文献

  1. ^ 「CLOSは標準です。複数のベンダーがCLOSを提供しています。CLOS(またはその一部)は、EuLispやEmacsLispなどの他のLisp方言にオブジェクト指向を追加するために使用されています。」p。Veitch1998の110
  2. ^ 動的言語のスライドの、Peter Norvigは、さまざまな教科書から取られた23のデザインパターンのうち16が、C ++よりもDylanまたはCommonLispで「見えないか単純」であるという彼の発見を示しています。
  3. ^ より近いプロジェクト:MOPに近い
  4. ^ COS、Cオブジェクトシステム
  5. ^ Cへのダイナセオブジェクト指向拡張
  6. ^ VCLOS、スキルのためのCLOS
  7. ^ GregorKiczalesによって開発されたTinyCLOS

文学