31

Clojureは機能的なLispであり、オブジェクト指向言語用に設計されたVMであるJVMで実行されているにもかかわらず、オブジェクト指向ではないと報告されています。Clojureは、リストとベクターをseqと呼ばれるインターフェースに抽象化することにより、それらを反復処理するための同一のインターフェースを提供します。これは、ISeqと呼ばれるJavaインターフェースを使用して内部的に実装されています。これはオブジェクト指向の抽象化の例ではありませんか?Clojureがオブジェクト指向ではないとどのように主張できますか?

この質問の当然の結果だと思います---ポリモーフィズムはいつオブジェクト指向とは異なると見なすことができますか?

4

4 に答える 4

31

慣用的な Clojure は、コア データ構造の非常に小さなセットで動作する独立した関数を定義することを好みます。このメソッドとデータの分離は、オブジェクト指向に強く反対し、機能的なスタイルを支持するものです。Rich Hickey (Clojure の作成者) は、これの重要性を繰り返し述べています。たとえば、「Clojure は、新しい状況ごとに新しいデータ型を作成するという従来のオブジェクト指向のアプローチを避け、代わりに小さな型のセットで関数の大規模なライブラリを構築することを好みます。」.

Clojure では、コア データ構造への依存が他の関数型言語よりもさらに重要です。Clojure の永続的なデータ構造を使用している場合にのみ、Clojure の STM の利点を最大限に享受できるからです。

私はこの質問の当然の帰結を推測します--- いつポリモーフィズムがオブジェクト指向と区別されると考えられるのでしょうか?

私は、Clojure のマルチメソッド (つまり、ポリモーフィック機能) を使用して、ファイル名の拡張子に基づいてさまざまな実装にディスパッチしています。オブジェクト指向ではなく、ポリモーフィックです。

于 2009-10-10T16:59:55.637 に答える
19

私はこの質問の当然の帰結を推測します--- いつポリモーフィズムがオブジェクト指向と区別されると考えられるのでしょうか?

ポリモーフィズムはオブジェクト指向とはまったく関係ありません。これは単に、オペランドのタイプに応じて、同じ操作が異なる動作をする可能性があることを意味します。

ML や Haskell などの関数型言語には 30 年以上にわたってポリモーフィズムがあり、PL の歴史をよく知っている人なら、1962 年より前 (つまり OO 以前) の例をいくつか指摘できるでしょう。

Christopher Strachey は 1967 年にパラメトリック ポリモーフィズムとアドホック ポリモーフィズムの違いを説明したため、その時点でポリモーフィズムはすでに存在していたに違いありません。ポリモーフィズムは Simula-67 の OO でのみ導入されたので、ポリモーフィズムは OO で導入される前に存在していたに違いないと思います。

于 2009-10-10T20:59:15.013 に答える
7

ISeq などは Java であることに注意してください。

Clojure では、seq の抽象化は、最初の関数、残りの関数、および n 番目の関数に提供できる単なる「何か」です (seq で最初に呼び出すのではなく、seq 引数を使用して最初に呼び出すことに注意してください)。Clojure 言語のコア関数はすべて、コレクション、seq、またはプリミティブ型で動作します。公開されたインターフェイスのメソッドにバンドルされたデータはありません。したがって、Clojure の実装は Java で行われ、JVM とのすべての相互運用性にはクラス/オブジェクトが関与しますが、Clojure 言語自体は関与しません。

メソッドをデータ構造にバンドルすることは、Clojure が思いとどまらせることです。

そうは言っても...現実には、関数には、どの引数を使用するかについて制限があります。first rest と nth は、seq になる可能性のあるものに対してのみ機能します。この観点からは、データ構造がメソッドにバンドルされているかどうかに大きな違いはありません。それでも、それらを正しく一致させる必要があります。大きな勝利は柔軟性から生まれます。関数は、任意の引数を取るように記述してから、クラスなどを定義せずに高階関数で構成できます。

(def farms [{:name "Swansea", :value 100}
            {:name "Broadmarsh", :value 200, :produce [:corn :wheat :rye]}
            {:name "Snug", :value 50, :animals [:goats :pigs]}])
(reduce + (map :value farms))
-> 350
(reduce + (map :value (filter :animals farms)))
-> 50
于 2009-10-13T00:27:26.440 に答える
4

Clojures ポリモーフィズムは、Java の自然な拡張機能です。Java では、クラスに応じてメソッドがディスパッチされます。clojure ではこれが拡張され、必要に応じて呼び出しをディスパッチできるようになっています。クラスで派遣するのはまだ本当に簡単ですが、実際、ほとんどの場合、それがどのように行われたかです。他のものが必要な場合は、独自のディスパッチャーを作成できます。derive必要なものに基づいて階層を作成し、次にディスパッチする組み込み関数isa

より良いもの: http://clojure.org/multimethods

于 2009-10-12T20:18:51.673 に答える