2011-12-02 83 views
7

有几次我遇到了uninterned符号的概念,但我不完全清楚它们是什么。Common Lisp中的无符号符号

有没有办法实习用(make-symbol)创造的符号?
我可以为一个符号赋值而不加入它吗?
是否可以重新命名一个符号(interned或uninterned)?
还有什么可以做一个未中断的符号?

更新:
这段代码中的符号发生了什么?

CL-USER> (defun func() 
      (let ((var 'sym)) 
      (print (find-symbol "sym")) 
      (print var))) 
FUNC 
CL-USER> (func) 

NIL 
SYM 
SYM 

我的不正确的理解是:
1.查找符号打印为零,所以符号不采访了
2. VAR打印SYM无#:在这意味着它是实习

+3

符号名称默认为英文。用FIND-SYMBOL查找它们区分大小写。 –

+0

我明白了,谢谢 (现在这个评论已经足够长了) – sabof

回答

8

未中断的符号主要用作名称或指示符以避免混乱的包或相关任务。

例如:

T1> (find-symbol "T2") 
NIL 
NIL 
T1> (find-symbol "T3") 
NIL 
NIL 
T1> (defpackage t2) 
#<Package "T2"> 
T1> (defpackage #:t3) 
#<Package "T3">  
T1> (find-symbol "T2") 
T2 
:INTERNAL 
T1> (find-symbol "T3") 
NIL 
NIL 

正如你可以看到,使用在第一defpackage形式实习生它在包t1t2,而在第二defpackage使用#:t3避免这一点。这是可能的,因为defpackage需要字符串指示符作为其第一个元素,并且不需要将符号作为指示符来执行操作。

这些和相关的情况是主要故意使用无间断符号的地方。您还可以避免使用字符串或关键字污染软件包,但在第一种情况下,可能是使用非默认可读格的人的问题,而在第二种情况下,您会污染关键字软件包,有些人关心。 (关于这是否真的很糟糕,有不同的意见。)

然后,有些情况下,一个符号丢失了它的家庭包装(例如unintern ing),并且显然至少变成了未中断。(它可能会在另一个包被拘禁。)

T1> (defparameter *t2* (find-symbol "T2")) 
*T2* 
T1> (import *t2* "T3") 
T 
T1> (symbol-package *t2*) 
#<Package "T1"> 
T1> (unintern *t2*) 
T 
T1> (find-symbol "T2") 
NIL 
NIL 
T1> (symbol-package *t2*) 
NIL 
T1> *t2* 
#:T2 
T1> (find-symbol "T2" "T3") 
#:T2 
:INTERNAL 
T1> (unintern *t2* "T3") 
T 
T1> (import *t2* "T3") 
T 
T1> *t2* 
T3::T2 
T1> (symbol-package *t2*) 
#<Package "T3"> 

所以,答案

有没有办法来实习生(使符号)创建一个符号?

是肯定的:

T1> (import (make-symbol "T4")) 
T 
T1> (find-symbol "T4") 
T4 
:INTERNAL 

我可以分配一个值的符号,而实习呢?

是的,当你失去它可以通过其名称和packagage被唯一标识,属性,你仍然可以使用它的价值插槽的plist等:

T1> (let ((symbol '#:t5)) 
     (setf (symbol-value symbol) 1) 
     (setf (get symbol :foo) :bar) 
     (setf (symbol-function symbol) (lambda())) 
     (values (symbol-value symbol) 
       (get symbol :foo) 
       (symbol-function symbol))) 
1 
:BAR 
#<Anonymous Function #xC829036> 

是有可能重新命名符号(interned或uninterned)?

修改符号名称的后果是未定义的。

用uninterned符号还能做什么?

我真的觉得他们大多用作包装的定义代号,但对一般的答案是:要命名的东西,而无需使用硬编码字符串他们可以在情况下非常有用,并且不希望污染任何包裹。

+0

还有一个问题,是否可以用同样的方式在词汇上实习/取消一个符号? – sabof

+0

我不明白这个问题。你能举一个例子或更详细的解释吗? – danlei

+0

我更新了问题 – sabof

1
    开始
  1. CL-USER> (intern (string (make-symbol "TEST"))) 
    TEST 
    :INTERNAL 
    
  2. 没有

  3. 它在包声明通常使用不污染包装,其中,所述声明发生(如果使用一个普通的符号)或关键字包的名称空间,因为在defpackage形式的:export条目和:use子句无论如何都转换为字符串。所以,你可以在函数中使用它,它接受任何东西并将其转换为字符串。更一般地说,无间断符号可以用作具有名称的唯一对象,而不是别的。但通常使用关键字符号来达到这个目的。

+2

我明白了4. 但是严格来说在1.你不是实习的符号,而是创建一个不同的名字 – sabof

+0

@sabof说得很对,你说得对。 –