Нарушение блокировки пакета COMMON-LISP при глобальном объявлении космического спец. - PullRequest
0 голосов
/ 20 мая 2018

Я пытался сделать что-то подобное в верхней части SBCL:

CL-USER> (defvar space " ")

Я получаю ошибку:

Lock on package COMMON-LISP violated when
globally declaring SPACE SPECIAL while in package
COMMON-LISP-USER.
   [Condition of type SYMBOL-PACKAGE-LOCKED-ERROR]

Restarts:
 0: [CONTINUE] Ignore the package lock.
 1: [IGNORE-ALL] Ignore all package locks in the context of this operation.
 2: [UNLOCK-PACKAGE] Unlock the package.
 3: [RETRY] Retry SLY mREPL evaluation request.
 4: [*ABORT] Return to SLY's top level.
 5: [ABORT] abort thread (#<THREAD "sly-channel-1-mrepl-remote-1" RUNNING {10025F6303}>)

Backtrace:
  0: (PACKAGE-LOCK-VIOLATION #<PACKAGE "COMMON-LISP"> :SYMBOL SPACE :FORMAT-CONTROL "globally declaring ~A ~A" :FORMAT-ARGUMENTS (SPACE SPECIAL))
  1: (SB-KERNEL:ASSERT-SYMBOL-HOME-PACKAGE-UNLOCKED SPACE "globally declaring ~A ~A" SPECIAL)
  2: (SB-C::PROCESS-VARIABLE-DECLARATION SPACE SPECIAL :SPECIAL)
  3: ((LABELS SB-C::MAP-NAMES :IN SB-C::%PROCLAIM) (SPACE) #<FUNCTION SB-C::PROCESS-VARIABLE-DECLARATION> SPECIAL :SPECIAL)
  4: (PROCLAIM (SPECIAL SPACE))
  5: (SB-IMPL::%DEFVAR SPACE #S(SB-C:DEFINITION-SOURCE-LOCATION :NAMESTRING NIL :INDICES 0) " " NIL)
  6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SB-IMPL::%DEFVAR (QUOTE SPACE) (SB-C:SOURCE-LOCATION) (UNLESS (BOUNDP #) " ")) #<NULL-LEXENV>)
  7: (SB-INT:SIMPLE-EVAL-IN-LEXENV (DEFVAR SPACE " ") #<NULL-LEXENV>)
  8: (EVAL (DEFVAR SPACE " "))
  9: ((LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1))
 --more--

Однако, когда я пытаюсь проверить и увидетьопределен ли space в пакете CL-USER, он говорит, что это не так.

The variable SPACE is unbound.
   [Condition of type UNBOUND-VARIABLE]

Restarts:
 0: [CONTINUE] Retry using SPACE.
 1: [USE-VALUE] Use specified value.
 2: [STORE-VALUE] Set specified value and use it.
 3: [RETRY] Retry SLY mREPL evaluation request.
 4: [*ABORT] Return to SLY's top level.
 5: [ABORT] abort thread (#<THREAD "sly-channel-1-mrepl-remote-1" RUNNING {10025F6303}>)

Backtrace:
  0: (SB-INT:SIMPLE-EVAL-IN-LEXENV SPACE #<NULL-LEXENV>)
  1: (EVAL SPACE)
  2: ((LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1))
 --more--

Почему это происходит?Если внутри пакета есть блокировка слова «пробел», почему он не связан?

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Однако, когда я пытаюсь проверить и определить, определено ли пространство в пакете CL-USER, он говорит мне, что это не так.

Ошибка произошла не потому, что вы пыталисьманипулировать символом space в пакете CL-USER, но символом space в CL, который доступен в CL-USER.

Проверка, является ли символ несвязанным, - не то же самое, что проверкадля его домашнего пакета.

Есть ли в пакете символ с именем space CL (он же COMMON-LISP)?

CL-USER 125 > (find-symbol "SPACE" "CL")
SPACE
:EXTERNAL

Есть несколько символов, которые не связаны, но в пакете CL.

0 голосов
/ 20 мая 2018

Первое: SPACE - это внешний символ в пакете COMMON-LISP в соответствии со стандартом.Он не связан как переменная или функция, но это символ, используемый в объявлениях, например, (declare (optimize (speed 2) (space 0))).

Second: есть много вещей, которые вы не можете делать с внешними символами вCOMMON-LISP пакет .Стандарт гласит, что последствия не определены, и в этом случае большинство реализаций решат сигнализировать об ошибке.В частности, номер 10 вас кусает:

Объявление или провозглашение его особенным

, потому что (defvar foo ...) провозглашение foo особенным.

Итак, ответ на ваш вопрос, почему вы не можете (defvar space ...) потому что SPACE является внешним символом пакета COMMON-LISP.Независимо от того, имеет ли оно привязку функции / переменной, эти ограничения применяются к всем внешним символам в COMMON-LISP.

. Вы могли бы обойти это путем затенения.SPACE в вашем пакете.Тогда символ SPACE, который вы объявляете особенным, будет не символом в пакете COMMON-LISP, а символом в вашем собственном пакете (который просто имеет то же имя).Но это все равно будет плохим стилем. Вы должны почти всегда использовать наушники вокруг специальных переменных. (defvar *space* " ") будет отлично работать (потому что *space* не является внешним символом в COMMON-LISP) и будет иметьдобавленное преимущество - не вводить в заблуждение тех, кто пытается прочитать ваш код (потому что мы ожидаем наушников вокруг специальных переменных).

...