Clojureにクラスを定義する方法が1つではなく5つあるのはなぜですか?


84

Clojureには、gen-class、reify、proxy、およびdeftypeとdefrecordがあり、新しいクラスのようなデータ型を定義します。構文の単純さを重視し、不必要な複雑さを嫌う言語にとって、それは異常のように思われます。なぜそうなのか誰かが説明できますか?Common Lispスタイルのdefclassで十分でしたか?

回答:


90

これは、3つの異なる要因の組み合わせです。

  1. jvmの特定の型システム
  2. タイプを定義する際のユースケースごとにわずかに異なるセマンティクスの必要性
  3. これらのいくつかは、言語が進化するにつれて、以前に開発され、いくつかは後で開発されたという事実。

それで、最初に、これらが何をするかを考えてみましょう。 deftypegen-classは、どちらも事前コンパイル用の名前付きクラスを定義するという点で似ています。Genクラスが最初に来て、clojure1.2でdeftypeがそれに続きました。Deftypeが推奨され、パフォーマンス特性は優れていますが、制限が厳しくなります。deftypeクラスはインターフェイスに準拠できますが、別のクラスから継承することはできません。

Reifyproxyはどちらも、実行時に匿名クラスのインスタンスを動的に作成するために使用されます。プロキシが最初に来て、reifyはclojure1.2のdeftypeとdefrecordとともに来ました。deftypeがそうであるように、セマンティクスがあまり制限されていない場合は、具体化が推奨されます。

それは、deftypeとdefrecordの両方が同時に出現し、同様の役割を果たしているので、なぜそれらの両方が同じような役割を果たしているのかという疑問を残します。ほとんどの目的で、defrecordを使用する必要があります。defrecordには、私たちが知っていて愛しているさまざまなclojureの良さ、シークアビリティなどがすべて含まれています。Deftypeは、他のデータ構造を実装するための低レベルのビルディングブロックとして使用することを目的としています。通常のclojureインターフェースは含まれていませんが、可変フィールドのオプションがあります(これはデフォルトではありませんが)。

詳細については、以下を確認してください。

clojure.orgデータ型ページ

deftypeとreifyが導入されたGoogleグループスレッド


1
グーグルグループのスレッドは非常に貴重でした。私の理解はjava-interopプロキシについてであり、gen-classは主にreifyとdeftypeに取って代わられています。現在、型を定義するための「推奨される」方法が少なくなっていることをうれしく思います。
サリル2011

2
@Trylks:オブジェクトをキーと値のペアのシーケンスとして扱う機能。clojureに固有のほとんどすべてをシーケンスとして扱うことができ、これは非常に強力です。
Rob Lachlan 2015年

proxy実行時にメソッドを変更できるため、この方法が好まれる場合があります。(例えば、The Joy of Clojure、第2版は、これがWebハンドラーのコールバックを変更するのに便利かもしれないことを示唆しています。)
火星

52

簡単に言えば、それらはすべて異なる有用な目的を持っているということです。複雑さは、基盤となるJVMのさまざまな機能と効果的に相互運用する必要があるためです。

Java相互運用機能が必要ない場合は、99%の場合、defrecordまたは単純なClojureマップのいずれかを使用するのが最善です。

  • プロトコルを使用する場合はdefrecordを使用します
  • それ以外の場合、通常のClojureマップはおそらく最も単純で最も理解しやすいものです

ニーズがより複雑な場合、次のフローチャートは、これらのオプションの1つを他のオプションよりも選択する理由を説明するための優れたツールです。

http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/

適切なclojureタイプ定義フォームを選択するためのフローチャート


1
フローチャートへのリンクをありがとう。ブログがO'reilly's-ProgrammingClojureの共著者によるものであることは助けになります。この意思決定は非常に複雑だと思います。インターフェイスと具象クラスの違いはありますか、静的メソッドを定義する必要があるかどうか、名前付き型または匿名型は非常に大きいため、異なる言語構造が必要ですか?
サリル2011

4
違いはそれほど大きくはありませんが、達成しようとしていることに関しては哲学的に異なります。Clojureの複数のアプローチは、これらの根本的な違いを反映していると思います。これが、異なる名前を付ける必要がある理由です。
mikera 2011

フローチャートは素晴らしいですが、1つまたは別のオプション、あるいはそれらの組み合わせを使用する可能性や理由のすべてを網羅しているわけではありません。簡単なチャートはできませんでした。
火星
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.