Wol*_*ane 0 symbols common-lisp
在Common Lisp程序中,我想找到一种方法来生成当时未在程序中使用的新符号.我知道(gensym)函数,但这会产生可能已存在于程序中的符号.我有一些理解,我需要实习符号,所以我尝试了这个:
(defun new-symbol () (intern (symbol-name (gensym))))
Run Code Online (Sandbox Code Playgroud)
这似乎得到了答案的一半.例如,
[1]> (new-symbol)
G3069
NIL
[2]> (new-symbol)
G3070
NIL
[3]> (defvar a 'G3071)
A
[4]> (new-symbol)
G3071
:INTERNAL
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,该函数似乎认识到符号'G3071'已经在其他地方使用,但我不知道如果是这样的话,如何生成新符号.
我知道(gensym)函数,但这会产生可能已存在于程序中的符号.
不,它没有.它会创建未在任何包中实现的符号.文件说(重点补充):
功能GENSYM
句法:
gensym&optionalx⇒new-symbol
论点和价值观:
x-a string或非负整数.复杂的违约行为; 见下文.
新符号 - 一个新鲜的,没有符号的符号.
您还可以使用make-symbol创建一个未在任何包中实现的符号.它的文档摘要(几乎与gensym的相同):
功能MAKE-SYMBOL
句法:
make-symbolname⇒new-symbol
论点和价值观:
name-一个字符串.
新符号 - 一个新鲜的,没有符号的符号.
关于你的第二点:
我有一些理解,我需要实习符号,所以我尝试了这个:
不,如果你想要一个新的符号,那么你可能不希望在任何地方实习.Interning是一个过程,您可以使用字符串(而不是符号)并在特定包中获取具有给定名称的符号.如果您使用相同的符号名称和包裹两次调用实习生,您将获得相同的符号,这是您要避免的.
CL-USER> (defparameter *a* (intern "A"))
*A*
CL-USER> (eq *a* (intern "A"))
T
Run Code Online (Sandbox Code Playgroud)
由于gensym使用*gensym-counter*生成新符号的名称,如果从gensym符号中取名称并在某处实习,如果有人修改了*gensym-counter*的值,则可以得到相同的符号.例如:
(let ((counter *gensym-counter*) ; save counter value
(s1 (gensym))) ; create a gensym (s1)
(setf *gensym-counter* counter) ; reset counter value
(let ((s2 (gensym))) ; create a gensym (s2)
(list s1
s2
(eq s1 s2)
(symbol-name s1)
(symbol-name s2)
(string= (symbol-name s1)
(symbol-name s2)))))
; (#:G1037 #:G1037 NIL ; different symbols
; "G1037" "G1037" T) ; same name
Run Code Online (Sandbox Code Playgroud)