: Экспорт из пакета в Common Lisp - PullRequest
2 голосов
/ 30 июня 2019

Я определил пакет, подобный следующему:

(defpackage :thehilariouspackageofamirteymuri
  (:nicknames ampack amir teymuri)
  (:use common-lisp)
  (:export say-hi-to))
(in-package :amir)

(defun say-hi ()
  "Docstring"
  "Hello")

(defun say-hi-to (who)
  (concatenate 'string (say-hi) " " who " from " (package-name *package*) "!"))

Теперь изменив пакет, также доступен # 'say-hi:

(in-package :amir)
(say-hi) ; -> "Hello"
(say-hi-to "World") ; -> "Hello World from THEHILARIOUSPACKAGEOFAMIRTEYMURI!"

Не является ли экспортКлючевое слово, говорящее, чтобы сделать вещи внешними для пакета?Почему внешняя # 'say-hi также экспортируется?

Ответы [ 2 ]

5 голосов
/ 30 июня 2019

Поскольку вы снова используете (in-package :amir), в этом пакете оцениваются следующие формы, так что вы можете использовать все функции, определенные в нем. Чтобы проверить, какие определения экспортируются, вам следует переключиться на другой пакет.

Давайте попробуем стандартный пакет CL-USER:

AMIR> (in-package :cl-user)
#<Package "COMMON-LISP-USER">
CL-USER> (say-hi)
Undefined function SAY-HI called with arguments ("world")  ; as expected, but...
CL-USER> (say-hi-to "world")
Undefined function SAY-HI-TO called with arguments ("world") ; ops!!
CL-USER> (amir:say-hi-to "world)
"Hello world from COMMON-LISP-USER!"
CL-USER> (amir:say-hi)
Reader error: No external symbol named "SAY-HI" in package #<Package "THEHILARIOUSPACKAGEOFAMIRTEYMURI"> .

Причина в том, что экспорт символа не означает, что мы можем использовать его без проверки его пакета. Однако, как вы можете видеть, только символы, экспортируемые из пакета, могут использоваться с «:». Если вы хотите использовать символ без имени пакета в качестве префикса, вы должны импортировать его раньше.

Итак, начнем снова.

CL-USER> (defpackage :another-package (:use :amir))
#<Package "ANOTHER-PACKAGE">
CL-USER> (in-package :another-package)
#<Package "ANOTHER-PACKAGE">
ANOTHER-PACKAGE> (say-hi-to "world")
"Hello world from ANOTHER-PACKAGE!"
ANOTHER-PACKAGE> (say-hi)
Undefined function SAY-HI called with arguments ()

Внутри ANOTHER-PACKAGE теперь вы можете использовать экспортированный символ без оговорок.

В общем, экспорт и импорт символов в пакетах в Common Lisp не так интуитивен, и хорошее описание всех тонкостей пакетов можно найти по ссылке, приведенной в другом ответе.

1 голос
/ 30 июня 2019

Проверьте разницу без изменения текущего пакета. Вы найдете больше информации, например, здесь

...