Common lisp defpackage和in-package调用的变化

Common lisp defpackage和in-package调用的变化,common-lisp,identifier,Common Lisp,Identifier,在格雷厄姆的书《ANSI通用Lisp》(1996)中。137说明defpackage和in-package的使用的示例如下 (defpackage "MY-APPLICATION" (:use "COMMON-LISP" "MY-UTILITIES") (:nicknames "APP") (:export "WIN" "LOSE" "DRAW")) (in-package my-application) defpackage调用使用字符串来传递包名和列出导出的符号。虽然这种风格

在格雷厄姆的书《ANSI通用Lisp》(1996)中。137说明defpackage和in-package的使用的示例如下

(defpackage "MY-APPLICATION"
  (:use "COMMON-LISP" "MY-UTILITIES")
  (:nicknames "APP")
  (:export "WIN" "LOSE" "DRAW"))

(in-package my-application)
defpackage调用使用字符串来传递包名和列出导出的符号。虽然这种风格可以在较旧的代码中看到,但今天的主要用法似乎是

(defpackage :my-application
  (:use :common-lisp :my-utilities)
  (:nicknames :app)
  (:export :win :lose :draw))

(in-package :my-application)
在defpackage和包内调用中使用
:my application
关键字所产生的规律性是一个微小但明显的差异

我推测,第二种形式减少了内存中程序的大小,因为关键字都在关键字包中,而文字字符串代表它们自己,具有相同内容的文字字符串不需要共享它们的内存表示。(如果他们真的这样做了,变异其中一个字符串可能会产生奇怪的结果!)

这两种形式之间的实际区别是什么?为什么后者比前者更受欢迎

除此之外,我偶尔会看到

;; Pay attention to the :export line
(defpackage :my-application
  (:use :common-lisp :my-utilities)
  (:nicknames :app)
  (:export #:win #:lose #:draw))

(in-package :my-application)
#
引入了一个reader宏,但我不确定它对关键字有什么影响,也不确定它如何修改defpackage声明。

tl;博士 使用不需要的符号,如
#:我的包

字符串指示符 Common lisp有一个 (另见)

这意味着在操作上 相当于 他们的名字

要使用哪个指示符? 您有4种选择:

1个实习符号 例如:

有利条件 简洁

缺点 名称空间污染:符号
my package
现在是 当前

2关键字 例如:

有利条件 适度简洁(额外增加一个字符)

缺点 名称空间污染:符号
:我的包
现在
在公园里

3串 例如:

有利条件 没有污染

缺点
  • 丑八怪
  • 2个额外字符
4非预期符号 例如:

有利条件 没有污染

缺点 2个额外字符

“丑陋的前缀”实际上是一个令人满意的特性,因为这是我使用不感兴趣的符号的唯一上下文,如果您添加这些符号,emacs会很好地突出显示它们

(font-lock-add-keywords
 'lisp-mode
 '(("\\(#:\\)\\(\\(\\s_\\|\\sw\\)*\\)"
    (1 font-lock-comment-delimiter-face)
    (2 font-lock-doc-face))))
到您的
~/.emacs

tl;博士 使用不需要的符号,如
#:我的包

字符串指示符 Common lisp有一个 (另见)

这意味着在操作上 相当于 他们的名字

要使用哪个指示符? 您有4种选择:

1个实习符号 例如:

有利条件 简洁

缺点 名称空间污染:符号
my package
现在是 当前

2关键字 例如:

有利条件 适度简洁(额外增加一个字符)

缺点 名称空间污染:符号
:我的包
现在
在公园里

3串 例如:

有利条件 没有污染

缺点
  • 丑八怪
  • 2个额外字符
4非预期符号 例如:

有利条件 没有污染

缺点 2个额外字符

“丑陋的前缀”实际上是一个令人满意的特性,因为这是我使用不感兴趣的符号的唯一上下文,如果您添加这些符号,emacs会很好地突出显示它们

(font-lock-add-keywords
 'lisp-mode
 '(("\\(#:\\)\\(\\(\\s_\\|\\sw\\)*\\)"
    (1 font-lock-comment-delimiter-face)
    (2 font-lock-doc-face))))
对于您的
~/.emacs

示例:

(defpackage "MY-APPLICATION"
  (:use "COMMON-LISP" "MY-UTILITIES")
  (:nicknames "APP")
  (:export "WIN" "LOSE" "DRAW"))

(in-package my-application)
人们通常会这样写:

(in-package "MY-APPLICATION")
如果在
defpackage
中使用字符串,那么在
中也会使用字符串

使用字符串或未插入符号的主要优点之一是避免用“不需要的”符号“污染”包

我推测,第二种形式减少了内存中程序的大小,因为关键字都在关键字包中,而文字字符串代表它们自己,具有相同内容的文字字符串不需要共享它们的内存表示。(如果他们真的这样做了,变异其中一个字符串可能会产生奇怪的结果!)

这是特定于实现的,取决于宏和底层数据结构的实现方式。例如,在LispWorks中,包对象的名称是字符串,昵称是字符串,使用列表是包对象的列表,导出的符号存储为符号。因此,
defpackage
表单中的数据将根据需要转换为这些数据

还要注意包的公共Lisp运算符将返回什么:
包名
返回字符串,
包使用列表
返回包对象列表,
执行外部符号
迭代符号。他们不使用关键字或未插入的符号。

您的示例:

(defpackage "MY-APPLICATION"
  (:use "COMMON-LISP" "MY-UTILITIES")
  (:nicknames "APP")
  (:export "WIN" "LOSE" "DRAW"))

(in-package my-application)
人们通常会这样写:

(in-package "MY-APPLICATION")
如果在
defpackage
中使用字符串,那么在
中也会使用字符串

使用字符串或未插入符号的主要优点之一是避免用“不需要的”符号“污染”包

我推测,第二种形式减少了内存中程序的大小,因为关键字都在关键字包中,而文字字符串代表它们自己,具有相同内容的文字字符串不需要共享它们的内存表示。(如果他们真的这样做了,变异其中一个字符串可能会产生奇怪的结果!)

这是特定于实现的,取决于宏和底层数据结构的实现方式。例如,在LispWorks中,包对象的名称是字符串,昵称是字符串,使用列表是包对象的列表,导出的符号存储为符号。因此,
defpackage
表单中的数据将根据需要转换为这些数据

还要注意包的公共Lisp运算符将返回什么:
package name
返回字符串,
package use list(in-package "MY-APPLICATION")