:EXPORT from Package in Common Lisp

2 export common-lisp package

I have defined a package like the following:

(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*) "!"))
Run Code Online (Sandbox Code Playgroud)

Now changing to the package also the #'say-hi is accessible:

(in-package :amir)
(say-hi) ; -> "Hello"
(say-hi-to "World") ; -> "Hello World from THEHILARIOUSPACKAGEOFAMIRTEYMURI!"
Run Code Online (Sandbox Code Playgroud)

Isn't the export keyword telling to make things external for the package? Why is the non-external #'say-hi also exported?

Ren*_*nzo 5

由于您将再次(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"> .
Run Code Online (Sandbox Code Playgroud)

原因是导出符号并不意味着我们可以在不限定其软件包的情况下使用它。但是,如您所见,只有从包装中导出的符号才能与“:”一起使用。如果要使用不带软件包名称的符号作为前缀,则必须先导入它。

因此,让我们重新开始。

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 ()
Run Code Online (Sandbox Code Playgroud)

在内部,ANOTHER-PACKAGE您现在可以无限制地使用导出的符号。

通常,在Common Lisp中,在包中导出和导入符号不是那么直观,并且可以在其他答案中引用的链接中找到对包的所有复杂性的良好描述。