1. ホーム
  2. clojure

[解決済み] なぜClojureではクラスを定義する方法が1つではなく、5つあるのですか?

2023-05-21 07:57:36

質問

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

どのように解決するのですか?

これは3つの異なる要因が混在しているのです。

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

ではまず、これらが何をするものなのかを考えてみましょう。 デフタイプ 遺伝子クラス は、どちらも先読みコンパイルのために名前付きクラスを定義するという点で似ています。 gen-classが最初に来て、clojure 1.2ではdeftypeがそれに続きました。 deftypeはより好まれ、より良いパフォーマンス特性を持っていますが、より制限的です。 deftypeクラスはインターフェイスに適合することができますが、他のクラスを継承することはできません。

Reify そして プロキシ はどちらも実行時に動的に匿名クラスのインスタンスを生成するために使われます。 Proxyが最初に来て、reifyはclojure 1.2でdeftypeとdefrecordと一緒に来ました。 Reifyは、deftypeがそうであるように、セマンティクスがあまりに制限的でない場合に、好まれます。

それは、なぜdeftypeとdefrecordの両方が同じ時期に登場し、同じような役割を持つのかという疑問を残します。 ほとんどの目的のために、私たちはdefrecordを使いたいと思うでしょう: それは、私たちが知っていて愛する様々なclojureの良さをすべて持っています。 Deftypeは他のデータ構造を実装するための低レベルのビルディングブロックとして使用することを意図しています。 それは通常のclojureインタフェースを含んでいませんが、ミュータブルフィールドのオプションがあります(これはデフォルトではありませんが)。

さらなる読書のために、チェックしてください。

clojure.orgのdatatypesページ

deftypeとreifyが紹介されたgoogleグループのスレッドです。