Незанятые символы в Common Lisp - PullRequest
8 голосов
/ 02 декабря 2011

Несколько раз я сталкивался с понятием непереданных символов, но мне не совсем ясно, что они собой представляют.

Есть ли способ интернировать символ, созданный с помощью (make-symbol)?
Могу ли я присвоить значение символу без его интернирования?
Можно ли переименовать символ (интернированный или не интернированный)?
Что еще можно сделать с непереданным символом?

Обновление:
Что происходит с символами в этом фрагменте кода?

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

NIL 
SYM 
SYM

Мое неверное понимание:
1. find-symbol печатает ноль, поэтому символ не имеет значения
2. var печатает sym без #: в начале, что означает, что он интернирован

Ответы [ 2 ]

8 голосов
/ 02 декабря 2011

Незамеченные символы в основном используются в качестве имен или обозначений, чтобы избежать загромождения пакетов или для связанных задач.

Например:

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

Как видите, использование t2 впервая форма defpackage помещает ее в пакет t1, а использование #:t3 во второй defpackage позволяет избежать этого.Это возможно, потому что 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">

Итак, ответ на

Есть ли способ интернировать символ, созданный с помощью (make-symbol)?

- это да:

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

Могу ли я присвоить значение символу без его интернирования?

Да, пока вытеряя свойство, которое может быть однозначно идентифицировано его именем и пакетом, вы все равно можете использовать его слот значения, 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>

Можно ли переименовать символ (интернированныйили нет)?

Последствия изменения имени символа не определены.

Что еще можно сделать с неинтернизированным символом?

Я действительно думаю, что они в основном используются в качестве обозначений в определениях пакетов, но общий ответ будет таким: они могут быть полезны в ситуациях, когда вы хотите назвать вещи без использования жестко закодированных строк и не хотите загрязнять какой-либо пакет.

1 голос
/ 02 декабря 2011
  1. Да

    CL-USER> (intern (string (make-symbol "TEST")))
    TEST
    :INTERNAL 
    
  2. Нет

  3. Нет

  4. Обычно он используется в объявлении пакета, чтобы не загрязнять пространство имен пакета, в котором происходит объявление (если использовался обычный символ), или ключевое слово package, поскольку записи в defpackage форме :export и :use предложения в любом случае преобразуются в строку. Таким образом, вы можете использовать его в функциях, которые принимают все и преобразуют его в строки. В более общем смысле неинтернизированные символы могут использоваться как уникальные объекты с именем и ничем иным. Но обычно для этой цели используются символы ключевых слов.

...