シンボルは、パッケージに含めることも、含めないこともできます。パッケージにインターンされたシンボルを検索して見つけることができます。パッケージ内でインターンされていないシンボルを検索することはできません。パッケージには、特定の名前のシンボルを 1 つだけ含めることができます。シンボルは 1 つだけCL-USER::FRED
です。
あなたが書く:
したがって、私が知る限り、インターンされていないシンボルは、エバリュエーターがシンボルとデータのバインディングを内部的に作成しないシンボルです。
それは間違っている。非インターンシンボルは、どのパッケージにもインターンされていないシンボルです。それ以外の場合は、完全に問題ありません。internedは、パッケージのレジストリにそのシンボルが登録されていることを意味します。
s-expressionリーダーは、読み取り中にシンボル名とパッケージを使用してシンボルを識別します。そのようなシンボルがない場合は、インターンされます。ある場合は、これが返されます。
リーダーは、現在のパッケージでシンボルを名前で検索します。
(read-from-string "FOO") -> symbol `FOO`
二度目:
(read-from-string "FOO") -> symbol `FOO`
常に同じ記号FOO
です。
(eq (read-from-string "FOO") (read-from-string "FOO")) -> T
#:FOO
という名前のインターンされていないシンボルの構文ですFOO
。どのパッケージにもインターンされていません。リーダーがこの構文を見ると、インターンされていない新しいシンボルが作成されます。
(read-from-string "#:FOO") -> new symbol `FOO`
二度目:
(read-from-string "#:FOO") -> new symbol `FOO`
両方のシンボルは異なります。名前は同じですが、異なるデータ オブジェクトです。パッケージ以外にシンボル用のレジストリはありません。
(eq (read-from-string "#:FOO") (read-from-string "#:FOO")) -> NIL
したがって、あなたの場合(LET ((#:G4315 1)) (PRINT (INCF #:G4315)))
、インターンされていないシンボルは異なるオブジェクトです。2 つ目は別の変数です。
Common Lisp にはデータを印刷する方法があるため、印刷/読み取り中に ID が保持されます。
CL-USER 59 > (macroexpand-1 '(test-macro))
(LET ((#:G1996 1)) (PRINT (INCF #:G1996)))
T
CL-USER 60 > (setf *print-circle* t)
T
CL-USER 61 > (macroexpand-1 '(test-macro))
(LET ((#1=#:G1998 1)) (PRINT (INCF #1#)))
T
#1=
印刷された s 式には、最初のシンボルのラベルがあることがわかります。その後、同じ変数を参照します。これは読み返すことができ、シンボルの同一性は保持されます -リーダーがパッケージを見てシンボルを識別できなくても。
したがって、マクロは、1 つのシンボルのみが生成されるフォームを作成します。そのフォームを印刷して読み返したい場合、インターンされていないシンボルの ID が保持されていることを確認する必要があります。*print-circle*
set toを使用して印刷するとT
、これを行うのに役立ちます。
GENSYM
Q: ( generate symbol )を使用して、インターンされていない生成済みシンボルをマクロで使用するのはなぜですか?
そうすれば、コード内の他のシンボルと衝突しない独自の新しいシンボルを作成できます。それらは関数によって名前を取得しますgensym
-通常、最後に数えられた数があります。これらはどのパッケージにもインターンされていない新しいシンボルであるため、名前の競合は発生しません。
CL-USER 66 > (gensym)
#:G1999
CL-USER 67 > (gensym)
#:G2000
CL-USER 68 > (gensym "VAR")
#:VAR2001
CL-USER 69 > (gensym "PERSON")
#:PERSON2002
CL-USER 70 > (gensym)
#:G2003
CL-USER 71 > (describe *)
#:G2003 is a SYMBOL
NAME "G2003"
VALUE #<unbound value>
FUNCTION #<unbound function>
PLIST NIL
PACKAGE NIL <------- no package