私は最近、引用、具体化、反省について混乱しています。誰かが彼らの関係と違い (もしあれば) について良い説明を提供できますか?
1 に答える
引用
これはおそらく最も簡単なものです。次のように REPL に入力するとどうなるかを考えてみてください。
(+ a 1)
REPL は Read Eval Print Loop の略なので、最初にこれを読み込みます。これはリストなので、読み込んだ後、<記号 "+"> <記号 "a"> <数字 1 を含む 3 つの要素のリストができます。 >
次のステップは評価です。Common Lisp でリストを評価するには、リストの最初の項目にバインドされた関数 (またはマクロ) を検索する必要があります。+ はマクロではなく関数にバインドされているため、リスト内の後続の各要素を評価します。数値はそれ自体に評価され、「a」はそれがバインドされているものに評価されます。引数が評価されたので、関数 "+" が評価の結果で呼び出されます。
次に、結果を印刷し、読み取りステップにループバックします
これは素晴らしいことですが、評価されたときに <記号 "+"> <記号 "a"> <数字 1> を含む 3 つの要素のリストになるものが必要な場合はどうでしょうか? これに対する解決策は引用です。Lisp は一般に、単一の引数を取る "quote" と呼ばれる特別な形式を持ち、その結果は評価されない引数になります。そう
(quote (+ a 1))
そのリストに評価されます。構文糖衣として、' は (quote ) と同じように扱われるので、単に '(+ a 1) と書くことができます。
具体化
具体化とは、「抽象的な概念を具体化すること」を大まかに意味する総称です。プログラミングに特有のことですが、何かが具体化されている場合、それは大まかに言えば、それをデータ (または「ファースト クラス オブジェクト」) として扱うことができることを意味します。Lisp でのこの例は関数です。ラムダ式を使用すると、関数呼び出しの抽象的な概念を表す具体的なファースト クラスのオブジェクトを作成できます。もう 1 つの例は、クラスの抽象的な概念を表す CLOS オブジェクトである CLOS クラスです。
反射
ある程度まで、リフレクションは具体化の反対です。具体的なものを考えると、その抽象表現に関する情報が必要になります。シンボル名からシンボルへの単なるマッピングである、パッケージの概念の具体化である Common Lisp Package オブジェクトを考えてみましょう。do-symbols を使用して、パッケージ内のすべてのシンボルを反復処理し、実行時にその情報を取得できます。
また、ラムダは関数の具体化であると言ったことを覚えていますか? さて、「function-lambda-expression」は関数の反映です。
メタオブジェクト プロトコル (MOP) は、クラスとオブジェクトであらゆる種類のことを行う準標準的な方法です。とりわけ、クラスとオブジェクトのリフレクションを可能にします。