2009-10-10 6 views
24

Clojureは、オブジェクト指向言語用に設計されたVMであるJVM上で動作しているにもかかわらず、オブジェクト指向では機能しないリスプです。 Clojureは、リストとベクタをseqと呼ばれるインタフェースに抽象化することによって、リストとベクタを反復するための同一のインタフェースを提供します。これはISeqと呼ばれるJavaインターフェイスを使用して内部的に実装されています。これはオブジェクト指向の抽象化の例ではありませんか? Clojureはオブジェクト指向ではないと主張することはできますか?Clojureはオブジェクト指向ですか? (一連の多態性)

私はこの質問に当てはまると思います---いつ多形性がオブジェクトの向きとは異なると考えることができますか?

+0

「オブジェクト指向ではないと報告されている」ソースへのリンクは、技術対政治です... –

+2

http://clojure.org/rationale OOPとClojureがそれを避ける理由について話しています。 –

+0

http://blog.thinkrelevance.com/2009/8/12/rifle-oriented-programming-with-clojure-2は、Clojureがどのように実際にすべての主要なOOプリンシパルの使用を許可するかを説明する興味深い記事です。しかし、私はそれらを組み合わせることは困難であることがわかります。例えば、クロージャーカプセル化を使用すると、継承による拡張が除外されます。一般的なアプローチは、拡張性のためにカプセル化を放棄することであるように思われる。 –

答えて

27

イディオム型Clojureは、非常に小さなコアデータセットで動作する独立した関数を定義することを優先します。この方法とデータのアンバンドリングは、オブジェクト指向と機能的スタイルに賛成する強い声明です。 Rich Hickey(Clojureの創作者)は、これの重要性を繰り返し述べました。たとえば、"Clojure eschews the traditional object-oriented approach of creating a new data type for each new situation, instead preferring to build a large library of functions on a small set of types."です。

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

私はこの質問に当てはまると思います---いつ多形性がオブジェクトの向きとは異なると考えることができますか?

私はClojureのマルチメソッド(多型機能)を使用して、ファイル拡張子に基づいて異なる実装にディスパッチします。オブジェクト指向ではなく、多態性です。

+14

"10個のデータ構造上の10個の関数よりも、100個の関数が1個のデータ構造上で動作する方が良いです。 - Alan J. Perlis – Jonas

16

私はこの質問に当てはまると思います。多形性はいつオブジェクト指向とは異なると考えることができますか?

多態性はオブジェクト指向とは全く関係ありません。これは単に、同じオペレーションがオペランドのタイプによって異なる動作をすることを意味します。

MLやハスケルのような機能言語は30年以上多形性があり、PL履歴の知識が豊富な人はおそらく1962年以前のいくつかの例を指摘している可能性があります(つまりpre-OO)。

Christopher Stracheyは、1967年のパラメトリック多型とアドホック多型の区別について記述しているので、多形性はがすでにである必要があります。多形性はSimula-67でOOに導入されただけなので、多形性はOOで導入される前にはが存在していなければなりません。

4

Clojures多態性は、Javaのnatrual拡張です。 Javaメソッドでは、クラスに応じてが送出されます。これは、あなたが望むものに基づいてコールをディスパッチできるように拡張されています。そのクラスで派遣するのはまだ本当に簡単です。あなたが何か他のものを望むなら、あなた自身のディスパッチャを書くことができます。組み込み関数deriveを使用して、必要なものに基づいて階層を作成し、isaにディスパッチします。で

より良:http://clojure.org/multimethods

5

ISEQのようなものは、Javaであることに注意してください。

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

データ構造を含むバンドル方法は、Clojureが嫌うものです。

実際には、機能にはどのような議論が機能するかに限界があります。最初の残りの部分とn番目の部分は、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 
関連する問題