构造大型Lisp应用程序

构造大型Lisp应用程序,lisp,common-lisp,quicklisp,asdf,Lisp,Common Lisp,Quicklisp,Asdf,我目前正试图将我的头脑集中在软件包、系统和公司上 我现在已经读了几遍了,我想我仍然很难把它弄对 如果我只是想将一个Lisp源文件拆分为两个文件,其中一个文件应该“使用”另一个文件——我该怎么做?我需要为此建立一个系统吗?我应该使用模块吗…?我来自Node.js的背景,在那里你可以简单地说 var foo = require('./foo'); 获取文件foo.js中导出内容的引用。在Lisp中,与此最接近的等效项是什么 我理解这是针对系统的,并且至少根据其文档,它是捆绑的一部分: ASDF与所

我目前正试图将我的头脑集中在软件包、系统和公司上

我现在已经读了几遍了,我想我仍然很难把它弄对

如果我只是想将一个Lisp源文件拆分为两个文件,其中一个文件应该“使用”另一个文件——我该怎么做?我需要为此建立一个系统吗?我应该使用模块吗…?我来自Node.js的背景,在那里你可以简单地说

var foo = require('./foo');
获取文件
foo.js
中导出内容的引用。在Lisp中,与此最接近的等效项是什么

我理解这是针对系统的,并且至少根据其文档,它是捆绑的一部分:

ASDF与所有最新版本的活动通用Lisp实现以及quicklisp[…]捆绑在一起

好的,Quicklisp是用于库的,但是它们之间的关系是什么?Quicklisp是否是其他语言中的“包管理器”?如果是这样,那么ASDF到底提供了什么


很抱歉问了这么多问题,但我认为这说明了我在理解如何构造Lisp应用程序时遇到的麻烦。任何帮助都将不胜感激:-)

在Common Lisp中有一个
require
函数,但它已被弃用。如果您只想将代码拆分为一个或多个部分,要在REPL中交互使用它,可以将代码放入不同的文件中,然后加载每个文件。如果您想编写一个完整的lisp项目,我发现这个包非常有用,它为创建新包提供了一个简单的起点。

System

对于构建大型系统,请使用系统管理工具。“免费”的是

您需要一个系统声明,其中列出了库或应用程序的各个部分。通常,它会进入自己的文件中。然后加载一个系统或编译一个系统。应该有如何做到这一点的教程

简单的Lisp系统可能有以下文件:

  • 一个系统文件,描述系统、其部件和任何其他需要的东西(其他系统)
  • 描述所用名称空间的包文件
  • 基本工具文件(例如宏使用的函数)
  • 列出宏的宏文件(用于在软件其余部分之前编译/加载宏)
  • 一个或多个具有功能的其他文件
Quicklisp独立于此。这是一个软件分发工具

编译和加载文件的快速破解

但是,您也可以不使用系统工具以老式方式编译和加载文件:

事实上可能还有更多,但通常已经足够了。编写自己的构建工具应该很容易。典型的系统工具将提供更多的功能,以结构化方式构建更复杂的软件。这些工具的许多想法至少可以追溯到35年前。例如,见1984年版第章

文件的作用

请注意,在普通的公共Lisp中,文件的角色及其语义并不十分复杂

文件是名称空间,它是与类/子类或对象关联,它是模块。您可以在一个文件中混合Lisp构造。文件可以是任意大的(例如,一个复杂的库有一个版本,其中它作为单个源文件提供,有30000行)。在标准语义中,文件扮演角色的唯一真实位置是编译文件时。编译文件有什么副作用?编译器可以做什么优化


除此之外,假定开发环境提供诸如加载和编译文件组(又称系统)、提供编译错误概述、记录定义的源位置、可以定位定义等服务。像ASDF这样的工具处理系统部分。

感谢quickproject的提示:-)此外,阅读并帮助理解包。谢谢:-)Rainer,关于ASDF,你为什么在“free”周围使用引号?另外,ASDF 3.1并不支持轻量级的快速构建/faslpath风格的系统构建,其中文件、包和系统之间存在一对一的对应关系。最后,与手动系统构建相比,ASDF所做的是允许您将软件开发与系统管理分离,因此您不需要指向您自己的文件的绝对路径名,更麻烦的是,它们的依赖关系都在您的构建规范中。ASDF将找到依赖项。请参见我关于Common Lisp作为脚本语言的演讲:
(defparameter *files*
  '("/yourdir/foo.lisp" "/yourdir/bar.lisp"))

(defun compile-foobar ()
  (mapc #'compile-file *files*))

(defun load-foobar ()
  (mapc #'load *files*))

(defun compile-and-load ()
  (mapc (lambda (file)
           (load (compile-file file)))
        *files*))