0

概要

純粋関数を、アルゴリズムを記述するパッシブオブジェクトと、それらのアルゴリズムを実行できるアクティブオブジェクトに分割することの長所と短所は何ですか?関数に副作用がないため、状況が大幅に簡素化されることに注意してください。

詳細

私が書いているコードの一部(Python 3で)は、主に関数型プログラミングに準拠しています。

いくつかの(不変の)データがあります。いくつかのアルゴリズムがあります。そして、それらのアルゴリズムをデータに適用して、結果を得る必要があります。

アルゴリズムは通常の関数として表すことができ、標準の操作を使用して変換されます(たとえば、2つの関数を作成し、を使用して一部のパラメーターをフリーズfunctools.partialし、結果の関数を引数として別の関数に渡すことができます)。パフォーマンス上の理由から、下位レベルの関数の多くはメモ化されます。

しかし、おそらくアルゴリズムをパッシブオブジェクトとして表現する必要があるという考えが浮かびました。そのようなオブジェクトは、それ自体では何も実行できません。実行する準備ができたら、アルゴリズムオブジェクトとそれが期待するすべての入力を特別な「計算」オブジェクトにフィードします。これは私のアルゴリズムのメンタルモデルとはるかによく一致しますが、このアプローチでいくつかの問題を見逃しているのではないかと心配しています。

アルゴリズムオブジェクトは、さまざまな方法で実装できます。おそらく、複数の実装も許可される可能性があります。私のアルゴリズムが抽象クラスAlgorithmのインスタンスであるとしましょう。その場合、そのサブクラスは次を表すことができます。

  • 作成するドメイン固有言語のテキスト文字列
  • 私が構築するある種の実行ツリー
  • 通常のPython関数でさえ

私はこれまでこれを行ったことがないので、このアイデアについてフィードバックをもらいたいと思いました。より「自然」であるという私の主観的な感覚は別として、それは実際のデザイン上の利点を提供しますか?問題はありますか?

4

1 に答える 1

1

デザインには大きなメリットやデメリットはないと思います。

任意の計算オブジェクトが任意のアルゴリズムを実行できると仮定すると、クラスAlgorithmにはおそらくexecute、アルゴリズムの実行方法を知っているようなものと呼ばれる関数が含まれることになります。その関数に名前を付ける__call__と、AlgorithmクラスはPythonの呼び出し可能オブジェクト(関数を含む)とまったく同じになります。

DSLコードの文字列の場合:設計では、インタープリターを実行するためAlgorithmにオーバーライドするサブクラスとしてそれらを表します。execute他の設計では、次のようなことを行うだけです。

def createDSLAlgorithm(code):
    def coderunner(*args, **kwargs):
        DSLInterpreter().interpret(code, *args, **kwargs)
    return coderunner

また、呼び出されたときに指定された式ツリーを実行する関数を作成するのと同様です。

もちろん、関数では不可能な、アルゴリズム設計に組み込むことを計画しているものが欠落している可能性があります。たとえば、すべてのPython関数に可変属性があるわけではありません。しかし、ユーザー定義関数はクロージャー、属性を持つことができ、実装するだけでどのオブジェクトも「関数のように振る舞う」ことができるので__call__、同じものの名前が異なるのではないかと思います。

もちろん、自分の名前を選択することは、コードの可読性を高めるのに役立つ場合、小さな利点です。また、計算オブジェクトがアルゴリズムの特定の既知の属性を調べて、それらを計算するときに何をするかを決定する場合は、属性を「関数」にアタッチするよりも「オブジェクト」にアタッチする方が少し自然に感じるかもしれません。 (たとえば、メモするかどうか)。

于 2012-09-09T22:06:02.160 に答える