5

この例を考えてみましょう。

パッケージ「a」で定義されている「first」という名前のクラスがあります。

モジュール「a」機能を使用するパッケージ「b」もあります。パッケージ「b」の特定の関数は、パラメータとしてクラス「first」のオブジェクトを必要とします。ただし、これ以外に、パッケージ「a」と「b」の間に直接の論理リンクはありません。

(defmethod package-b-function ((param first)) #|do stuff..|#)関数にはオブジェクトが必要であり、メソッドを定義すると、ランタイム環境とパッケージ'b'の他のユーザーの両方に対してこれが明確になるため、通常の関数の代わりに記述するのが合理的かどうか疑問に思います。

私は以前C++/ Javaでプログラミングしていたので、この場合に使用されるOOP規則に精通していません。

あなたの洞察に感謝します。

4

3 に答える 3

9

Common Lispのメソッドは、あなたが注意する言語とまったく同じようには機能しません(詳細については、 Practical Common Lispの適切な2つの章を参照してください)。一言で言えば、非常に高いレベルでは、LispのOOを「クラスにはメソッドがある」というよりも「メソッドはクラスに特化している」と考える必要があります。

そうは言っても、他の場所で定義されているクラスに特化したメソッドをパッケージに含めることは完全に合理的だと思います。期待する入力のタイプを指定すると、将来の読者の意図が明確になります(最適化に役立つ場合と役に立たない場合がありますが、私の観点からはそれほど重要ではありません)。パッケージにASDFシステムを定義する場合はimport、適切な記号と適切なパッケージを確認してくださいdepends-on

length脚注と同じように、Common Lispは言語として特にオブジェクト指向ではないことに注意してください(たとえば、特定のクラスに、popまたはpushメソッドを含めるか、算術演算に特化する必要があると判断した場合、奇妙なコーナーに遭遇します) 。

于 2012-08-03T15:58:05.810 に答える
4

Common Lispは、通常の関数とジェネリック関数を提供します。

最初のルールとして、これを使用します。

利用可能なさまざまなメソッドから効果的なメソッドをアセンブルする場合(たとえば、Mixinsを使用してプログラミングする場合)、またはランタイム引数に基づいてメソッドを選択する場合は、ジェネリック関数を使用します。

この高度な動作が必要ない場合は、通常の関数を使用してください。通常の関数が必要とする引数の種類と対応するランタイムチェックを文書化することは、他のCL機能を使用して実行できます。

  • CHECK-TYPE
  • ASSERT
  • ドキュメント文字列
  • DECLARE引数の種類
于 2012-08-07T08:02:00.033 に答える
1

すでに述べたように、関数とメソッドの両方が、説明するシナリオの純粋に技術的なPOVから正常に機能します。Inaimathiの回答(および質問のテキスト)は、使用する理由を示していますdefmethod(読者への意図のより良いコミュニケーション、より良いコンパイラ情報)。代わりにプレーン関数を使用する理由の1つは、設計の初期段階と探索的プログラミングの両方でリファクタリングを支援することです。一般的なCL手法は、関数が他の関数(たとえば、あなたの場合、a:first内のスロットを取得/設定するアクセサーpackage-b-function)にのみ渡される引数を受け入れることです。

package-b-function関数を作成すると、クラスの名前を変更a:firstしたり、クラスから構造体、リスト、ベクトルに変更したり、パフォーマンス測定を行ったりすることができます。中間者package-b-functionとその50人の兄弟は作業を続けます。を使用して型情報をエンコードする場合defmethod、システムの基本的なデータ構造を変更するときに多くのコードを変更する必要があるため、「5要素のベクトルを使用した場合に処理が速くなるか」などの質問に簡単に答えることはできません。ここのオブジェクトの代わりに?」svrefそれ以外の場合は、代わりに実行する5つのアクセサー関数と、の代わりslot-valueに呼び出すファクトリを定義するだけです。vectormake-instance

于 2012-08-07T07:50:31.020 に答える