web-dev-qa-db-ja.com

10個のデータ構造で10個の関数を使用するよりも、1個のデータ構造で100個の関数を操作する方がよいのはなぜですか。

私はこれが多くの場所で引用されているのを見てきました:

「10個のデータ構造で10個の関数を操作するよりも、1個のデータ構造で100個の関数を操作する方がよいでしょう。」 —アラン・パリス

しかし、なぜこれが真実であるのかを説明しているのを見たことがありません。データの重複を避けるために、最初から他の9つのデータ構造を導出しようとする必要があるという考えだけですか?文脈が欠けているような気がします。

64
GlennS

引用は、1982年に発行されたAlan Perlisの プログラミングのエピグラム からのものです。

この引用の意味は [〜#〜] lisp [〜#〜] でよく具体化されており、リストを具体的に操作および処理する関数が多数あります。 そして、リストとリストを操作する関数の組み合わせだけで多くのことを達成できます。これにより、リストは単一目的のデータ構造よりもはるかに強力になります。

Lua 、別の例として、 テーブルを使用してクラスをシミュレートします 。言語レベルのクラスやオブジェクト指向言語のようなオブジェクトを作成する代わりに、テーブルを使用してオブジェクトを作成するのはなぜですか?オブジェクトはテーブルになっているので、オブジェクトのテーブルに定義されている関数をいくつでも無料で使用できます。さらに良いことに、クラス固有の構文で言語を乱雑にする必要はなく、クラスに必要なテーブルから関数を再定義する必要もありませんでした。

Perlisが言ったことは、LISPおよび 関数型プログラミング 一般において間違いなく顕著な考え方です。 1つのデータ構造上のこれらの100個の関数は、すべて同じデータ構造で動作するため、多くの独自の方法で組み合わせることができますが、10個の関数を10個のデータ構造上で定義しただけなので、実際に混合することはできません特定のデータ構造に取り組む。

これのより現代的で単純なバリエーションは、抽象化の観点から考えています。 Javaでコーディングしている場合は、 List インターフェイスで100個の関数を作成するか、同じ10個の関数のセットをArrayList用に1回、LinkedList用に1回、...用に1回作成します。

85
Zach L

コンピュータプログラムの構造と解釈(SICP)は、以下のようにあなたの質問に答えます。

Screenshot from SICP

この本の オンライン版の元の内容はここで見ることができます

編集(コメントから含まれています):

「Pascalでは、宣言可能なデータ構造が多すぎると、関数内に特殊化が生じます。」専門化は、私自身の言葉で「セレンディピティ」/創造性を阻害するため、悪いことです。

つまり、関数が特殊すぎると、関数の作成時に認識されていなかった方法で再利用できなくなります。

良い例はfoldhttps://hackage.haskell.org/package/base-4.8.1.0/docs/Data-Foldable.html )これはデータ構造にとらわれない一般的な高階関数です。たとえば、ツリーで使用できます

data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a).
9
jhegedus