Common Lisp将包名附加到宏中的引用键

Mak*_*nix 2 symbols common-lisp package

我注意到Common Lisp中的以下行为(至少使用SBCL),我能够将其减少到以下内容:

假设我有以下宏:

(defpackage "MY-TEST"
  (:use "COMMON-LISP")
  (:export :appended
       :not-appended))

(in-package :MY-TEST)

(defmacro not-appended ()
  `(list ':type 'array))

(defmacro appended ()
  `(list ':type 'something-else))
Run Code Online (Sandbox Code Playgroud)

以下是输出:

* (my-test:not-appended) 
(:TYPE ARRAY)


* (my-test:appended) 
(:TYPE MY-TEST::SOMETHING-ELSE)
Run Code Online (Sandbox Code Playgroud)

请注意,在第二个宏中,命名空间位于"SOMETHING-ELSE"之前.

问题:

  • 为什么他们有所不同?老实说,我期待"未附加"宏的行为.这是因为Common Lisp以某种方式知道"数组"吗?
  • 如果是,那么我在哪里可以找到其他已知关键字?

Rai*_*wig 7

请注意,这与宏完全无关,并且是包,符号和符号打印方式的影响:

包'MY-TEST':

CL-USER 2 > (defpackage "MY-TEST"
              (:use "COMMON-LISP")
              (:export :appended
               :not-appended))
#<The MY-TEST package, 0/16 internal, 2/16 external>
Run Code Online (Sandbox Code Playgroud)

通过调用使包成为当前包in-package:

CL-USER 3 > (in-package :MY-TEST)
#<The MY-TEST package, 0/16 internal, 2/16 external>
Run Code Online (Sandbox Code Playgroud)

让我们计算符号列表arrayfoo.查看REPL如何打印它,(ARRAY FOO)因为两个符号都可以在包中访问MY-TEST.

MY-TEST 4 > (list 'array 'foo)
(ARRAY FOO)
Run Code Online (Sandbox Code Playgroud)

制作CL-USER当前套餐:

MY-TEST 5 > (in-package :cl-user)
#<The COMMON-LISP-USER package, 151/256 internal, 0/4 external>
Run Code Online (Sandbox Code Playgroud)

现在让我们得到倒数第二个值,看看REPL如何打印它:

CL-USER 6 > **
(ARRAY MY-TEST::FOO)
Run Code Online (Sandbox Code Playgroud)

ARRAY打印时没有包前缀,因为它与包中的符号相同COMMON-LISP(在包中使用MY-TEST).FOO使用包前缀打印MY-TEST,因为它是该包中的内部符号 - 它是在那里实现的,因为那时当前的包是MY-TEST.有两个冒号,因为符号FOO不从包中导出的MY-TEST,它也不会导入到软件包CL-USER.

包"CL"和"CL-USER"包含编程语言Common Lisp中的所有符号 - 因此将"CL"导入到您自己的包中也会使该包中的所有符号都可用.

CL-USER 7 > (let ((l '()))
              (do-symbols (sym (find-package "CL") l)
                (pushnew sym l)))
(MAKE-ARRAY INVOKE-DEBUGGER STRING-TRIM WILD-PATHNAME-P UNREAD-CHAR RESTART-BIND ...
Run Code Online (Sandbox Code Playgroud)