この質問についてよく考えてみると、シンボルと変数を区別する理由、または Omri がよく言ったように、「シンボルをその基になる値にマッピングするために 2 レベルの間接化」を使用する理由がいくつか考えられます。最後に最高のものを保存します...
1: 「変数」と「変数を参照できる識別子」の概念を分離することで、Clojure は概念を少しすっきりさせます。CL では、リーダーがを参照 すると、現在のスコープでローカルにバインドされている場合でもa
、トップレベルのバインドへのポインターを運ぶシンボル オブジェクトが返されます。(この場合、エバリュエーターはそれらのトップレベルのバインディングを利用しません。) Clojure では、シンボルは単なる識別子であり、それ以上のものではありません。 a
これは、シンボルが Clojure の Java クラスも参照できるという一部の投稿者が作成したポイントに関連しています。シンボルにバインディングが含まれている場合、シンボルが Java クラスを参照するコンテキストではそれらのバインディングを無視できますが、概念的には面倒です。
2: 場合によっては、シンボルをマップ キーなどとして使用したい場合があります。シンボルが (CL のように) 可変オブジェクトである場合、Clojure の不変データ構造にはうまく適合しません。
3: (おそらくまれですが) シンボルがマップ キーなどとして使用され、API によって返されることさえある場合、Clojure のシンボルの等価セマンティクスは CL のシンボルよりも直感的です。(@ amalloyの回答を参照してください。)
partial
4: Clojure は関数型プログラミングを重視しているため、多くの作業は、comp
、などの高階関数を使用して行わjuxt
れます。これらを使用していない場合でも、関数を独自の関数などの引数として使用できます。
my-func
これで、高階関数に渡すと、 「my-func」と呼ばれる変数への参照が保持されなくなります。今ある価値をそのまま捉えているだけです。後で再定義my-func
すると、変更は の値を使用して定義された他のエンティティに「伝播」しませんmy-func
。
このような状況でも、 を使用すると、派生関数が呼び出されるたび#'my-func
に の現在の値を参照するように明示的に要求できますmy-func
。(おそらく、小さなパフォーマンス ヒットを犠牲にして)。
CL や Scheme では、この種の間接化が必要な場合、cons、vector、または struct に関数オブジェクトを格納し、呼び出されるたびにそこから取得することを想像できます。実際、コードのさまざまな部分で共有できる「可変参照」オブジェクトが必要なときはいつでも、コンスまたはその他の可変構造を使用することができました。しかし、Clojure では、lists/vectors/etc. すべて不変であるため、「変更可能なもの」を明示的に参照する方法が必要です。