2016-05-10 2 views
2

Я понимаю, что разница междуКлючевое загрязнение пространства имен

(defpackage :foo 
    (:export :bar)) 

и

(defpackage :foo 
    (:export #:bar)) 

является то, что последний не стажер bar в KEYWORD пакет. Мой вопрос в том, есть ли смысл в этом? Похоже, что точка пакета KEYWORD должна использоваться для интернирования ключевых слов.

ответ

4

Пакет используется для хранения пространств имен символов. Пакет имеет имя и символы, имеющие имена. Обычно один получает эти имена как строки и, таким образом defpackage формы может использовать строки для имен:

(defpackage "FOO" 
    (:export "BAR")) 

Над описания пакета не понравился некоторые, так как он предоставляет случай идентификаторов. Обычно это не проблема, но существуют нестандартные версии Common Lisp, где по умолчанию символы могут быть более строчными.

Поскольку можно использовать символы в качестве имен (и только имя достоверна) в DEFPACKAGE форме мы можем написать:

(defpackage :foo 
    (:export :bar)) 

или

(defpackage #:foo 
    (:export #:bar)) 

или даже

(defpackage cl-user::foo 
    (:export cl-user::bar)) 


CL-USER 22 > (find-symbol "BAR" "FOO") 
FOO:BAR 
:EXTERNAL 

Обычное ожидание состоит в том, что символы без ссылок, интернированные в пакеты, не могут быть удалены Сборщик мусора (GC) - стандарт Common Lisp ничего не говорит об этой теме и не требует никакого поведения. Поэтому добавление новых символов в пакет часто увеличивает его. Это может быть утечка памяти в некоторых приложениях.

Другим обычным ожиданием будет то, что unreferted и uninterned символы будут освобождены GC.

Если вы не возражаете, что есть много (независимо от того, что средства) символов в пакете ключевого слова, то это не проблема.

Типичные проблемы с большими пакетами могут быть:

  • интернированных символы не могут быть GCed
  • там может быть некоторые затраты скорости связаны с использованием больших пакетов

Для типичного DEFPACKAGE формы я бы не ожидайте заметной проблемы, поэтому можно предпочесть один вариант по каким-либо стилистическим причинам.

+0

«нестандартные версии Common Lisp»: даже если стандарт указывает, что такое случай по умолчанию, его можно изменить, не так ли? Предполагая, что переменные установлены в их значения по умолчанию, обычно небезопасны. На практике некоторые библиотеки в Quicklisp faill для сборки при изменении по умолчанию. – coredump

+0

@coredump: ANSI Common Lisp требует, чтобы (symbol-name 'cl: defun) был «DEFUN», а не «defun», а не «deFun». В некоторых вариантах Common Lisp есть символы - даже стандартные CL - все сбиты внутри.Идея состоит в том, что уменьшенные символы упрощают взаимодействие с внешними системами. –

+0

Что касается GC, в стандарте упоминается, что пакет имеет внутренние символы, символы затенения и экспортированные символы. Не ожидается, что символы, упомянутые в любом из этих списков, из любого живого пакета (то есть не самого собираемого) будут собраны в мусор. – acelent