为什么许多Common Lisp系统使用单个packages.lisp文件?

ant*_*sis 5 common-lisp

我看到的许多常用库使用单个packages.lisp文件在一个地方声明库(系统)中的所有包.

由于导出的符号是包定义的一部分,因此这意味着单个源文件不会列出其导出的符号.

在我自己的项目中,我更喜欢每个包定义一个源文件的样式,并在文件顶部定义其接口/导出.

我想知道我是否做错了,或者错过了导致偏好单个packages.lisp文件的基本概念.

如果它是相关的,我也使用ASDF的:package-inferred-system方法,而uiop:define-package不是defpackage,利用它的方便的符号阴影:mix功能 - 因为我还没有弄清楚如何:use一个阴影内置符号的包没有重新声明使用它的每个包中的阴影.

Rai*_*wig 12

使用包的传统观点

有时,包(符号命名空间)在数十甚至数百个文件中使用,并且可能需要计算包.这在一个文件中可能更简单,当包声明在一个文件中时,可能更容易获得文本概述.例如,文本编辑器的实现可以在一个包中使用大约100个文件.另请注意,程序包实际上是Common Lisp中带有程序员接口的运行时数据结构.

来自Java等其他语言的影响

拥有一个包和一个相应源文件的样式通常来自Common Lisp之外,来自通常具有类似于一个类 = 一个名称空间 = 一个文件的对应的语言.这导致嵌套目录中的大量文件,每个文件通常有一小段代码.

Common Lisp没有这些限制:方法不是在类中组织,类不是命名空间,文件可以有任何混合的定义,...... Lisp库往往有大型包/命名空间和大文件.

结构及其局限性

包

Common Lisp中的包是符号的名称空间.这不是一个完整的模块系统.此外,没有实际的信息隐藏.符号和导出符号之间存在区别.另请注意,符号具有多个含义作为名称(变量,函数/宏/特殊运算符,类名,插槽名称,类型,数据对象,包名称......),并且从包中导出符号不会有所区别在这些意义之间.另请注意,可以(但不建议)在文件中使用多个程序包名称空间(例如,通过使用多个in-package表单).通常,文件中只有一个名称空间.这通常是由in-package文件顶部的某个地方声明的.

类

类不是命名空间.通常,类是使用内置的Common Lisp对象系统定义的,称为CLOS.它们捆绑了插槽,用于在CLOS通用函数中进行调度.但他们不包含他们的方法.

系统

系统不是语言结构.它们是Common Lisp的扩展.系统的想法由ASDF等工具提供.系统是用于组织构成库/应用程序及其依赖项的一堆文件的工具.它也是在系统上使用动作(编​​译,加载,传递......)的功能.

???

为了更好地组织代码,可能会缺少一些东西.每个项目可能需要稍微不同的方式.

我通常会使用文件将相关功能放入一个文件中,并为系统设置一堆文件 - 如果需要的话.但这可能意味着文件实现了多个类和许多功能.我倾向于在实现直接相关代码的部分组织文件.我可能会在文件顶部描述一些元素(类,函数),但这更像是本地概述而不是导出符号列表.一旦你用它的IDE将系统及其文件加载到Lisp中,开发环境的目的是让我查询代码(在哪里?谁使用?使用什么?sub/super class?包内容?.. .)并为此提供浏览器.

有其他方法来组织代码.例如,通过使用PROVIDE和REQUIRE,这些只是语言标准中非常简单的描述.这些往往会根据需要提供功能,并随时随地创建包结构.

可能需要像面向对象的协议,它为CLOS提供更多的结构.

在MIT Lisp Machine操作系统中尽早使用软件包和系统

避免名称冲突和系统组织代码的软件包的早期需求之一来自于70年代末和80年代在麻省理工学院开发的Lisp Machine操作系统.它是在Lisp Machine Lisp中开发的,后来在Common Lisp中开发.在那里,许多不同的功能(编译器,编辑器,监听器,检查器,邮件客户端,图形库,文件系统,串行接口,以太网接口,网络代码......)在一个地址空间中运行,可能有数万个的符号.包声明的,通常是对应的系统描述文件来完成(在这里我们再次使用的Lisp的意义系统作为库或应用程序,文件为某种目的的集合)或有时在一个单独的文件.包为大型库甚至整个应用程序提供了命名空间.因此,文件,包,系统甚至类(之前称为Flavors)已经被用于构建软件实现.请参阅Lisp机器手册(1984年版本),第29章,维护大型系统和Kent Pitman的MIT AI Memo 801(1984年:大型系统描述).Lisp Machine上的系统具有版本并支持修补(增量版本更改).文件也有版本.

  • @anticrisis:只是它不太适合通常的 Lisp 风格。使用大量带有每个文件命名空间的小文件几乎没有优势。最后它比使用更大的包更令人困惑。由于 Lisp 不提倡严格的信息隐藏,因此在 Lisp 中模拟 class=namespace=file 编程风格几乎没有意义。 (2认同)
  • package.lisp 文件通常也提供了一个很好的系统概览。你可以从[这些](https://github.com/quicklisp/quicklisp-client/blob/master/quicklisp/package.lisp#L137) [例子](https://github.com/cffi/cffi/ blob/master/src/package.lisp#L30),符号按逻辑分组,很容易看到包昵称、导入、阴影和阴影导入。 (2认同)