Symbole mogą być internowane w pakiecie lub nie. Symbol internowany w pakiecie można wyszukać i znaleźć. Nieopisanego symbolu nie można znaleźć w paczce. Tylko jeden symbol pewnej nazwy może znajdować się w paczce. Jest tylko jeden symbol CL-USER::FRED
.
Piszesz:
Więc o ile wiem, że uninterned symbole są symbolami, dla których oceniający does't tworzyć wiązania wewnątrz symbolu danych.
To źle. Niezainicjowane symbole są symbolami, które nie są internowane w żadnym opakowaniu pod numerem . W przeciwnym razie są idealnie w porządku. internowany oznacza zarejestrowany w rejestrze pakietu rejestru dla swoich symboli.
Identyfikator s 013185160993835102 s-expressionwykorzystuje nazwę symbolu i paczkę do identyfikacji symboli podczas czytania odczytu. Jeśli nie ma takiego symbolu, jest internowany. Jeśli istnieje, to ten jest zwracany.
Czytelnik nie patrzeć symbole ich imieniu, tutaj w obecnym pakiecie:
(read-from-string "FOO") -> symbol `FOO`
po raz drugi:
(read-from-string "FOO") -> symbol `FOO`
to jest zawsze taki sam symbol FOO
.
(eq (read-from-string "FOO") (read-from-string "FOO")) -> T
#:FOO
jest składnia dla uninterned symbol z nazwą FOO
. Nie jest internowany w żadnym pakiecie. Jeśli czytelnik zobaczy tę składnię, tworzy nowy nieopisany symbol.
(read-from-string "#:FOO") -> new symbol `FOO`
czas drugiego
(read-from-string "#:FOO") -> new symbol `FOO`
Obydwa symbole są różne. Mają takie same nazwy, ale są to różne obiekty danych. Nie ma innego rejestru symboli, niż pakiety.
(eq (read-from-string "#:FOO") (read-from-string "#:FOO")) -> NIL
Zatem w przypadku (LET ((#:G4315 1)) (PRINT (INCF #:G4315)))
, że uninterned symbole są różne obiekty. Drugi to inna zmienna.
Common Lisp ma sposób, aby wydrukować dane, tak że tożsamość jest zachowana podczas drukowania/odczyt:
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
Teraz widać, że drukowane s-wyrażenie ma etykietę #1=
dla pierwszego symbolu . Następnie odwołuje się do tej samej zmiennej. To może być odczytywane z powrotem, a tożsamości symboli są zachowywane - nawet jeśli czytnik nie może zidentyfikować symbolu, patrząc na opakowanie.
W ten sposób makro tworzy formularz, w którym generowany jest tylko jeden symbol. Kiedy drukujemy ten formularz i chcemy go odczytywać, musimy upewnić się, że tożsamość niezainternowanych symboli została zachowana. Drukowanie z ustawieniem *print-circle*
na T
pomaga to zrobić.
Q: Dlaczego używamy uninterned wygenerowanych symboli makr za pomocą GENSYM
(wygenerowania symbolu)?
W ten sposób możemy mieć unikalne nowe symbole, które nie kolidują z innymi symbolami w kodzie. Otrzymują nazwę przez funkcję gensym
- zwykle z policzoną liczbą na końcu. Ponieważ są one świeżymi, nowymi symbolami, które nie są internowane w żadnym pakiecie, nie może być żadnego konfliktu nazw.
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
Gdybym zrozumiał swoje wyjaśnienie poprawnie, 'gensym' będzie nadal działać poprawnie, nawet jeśli nie liczy się ilość dodać do nazwy symbolu, czyli jeśli to zwrócił uninterned symbol o tej samej nazwie za każdym razem to się nazywa (z tym samym argumentem). Czy to jest poprawne? Jeśli tak, to dlaczego dodaje numer? Żeby łatwiej było stwierdzić, które symbole są takie same i które nie są na wyjściu 'makro-rozszerzenia'? – sepp2k
@ sepp2k: poprawne, liczba jest po to, aby ułatwić wykrycie, gdzie symbole niezamieszkane są różne i które mogą być takie same. To jest pomoc do debugowania. We wcześniejszych dialektach Lispa (bez pakietów) mogło być ważniejsze. –
Wielkie dzięki. Objaśnienie * print-circle * naprawdę pomaga zrozumieć, jak to działa. I dziękuję za wyjaśnienie również o niezamierzonych symbolach. – JustAnotherCurious