构建大型Lisp应用程序

时间:2015-06-12 15:19:38

标签: lisp common-lisp quicklisp asdf

我目前正试图围绕包裹,系统和共

我现在已经阅读了Packages, systems, modules, libraries - WTF?几次,而且我认为我仍然难以做到正确。

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

var foo = require('./foo');

获取对文件foo.js中导出内容的引用。 Lisp中与此最接近的是什么?

我理解ASDF适用于系统,并且它是Quicklisp的一部分,至少根据其文档:

  

ASDF捆绑了所有最新版本的活动Common Lisp实现以及quicklisp [...]

好的,Quicklisp适用于图书馆,但他们的关系是什么? Quicklisp是其他语言中的“包管理器”吗?如果是这样,那么ASDF到底提供了什么?

很抱歉这些问题很多,但我认为这只是表明我必须了解如何构建Lisp应用程序的麻烦。任何帮助将不胜感激: - )

2 个答案:

答案 0 :(得分:8)

<强>系统

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

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

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

  • 系统文件,描述系统,其部件和其他需要的东西(其他系统)
  • 描述所用命名空间的包文件
  • 基本工具文件(对于宏使用的示例函数)
  • 一个列出宏的宏文件(用于在软件的其余部分之前编译/加载它们)
  • 一个或多个具有功能的其他文件。

Quicklisp独立于此。它是一个软件分发工具。

快速破解编译和加载文件

但您也可以在没有系统工具的情况下以旧式方式编译和加载文件:

(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*))

实际上可能会有更多,但通常它就足够了。编写自己的构建工具应该很容易。典型的系统工具将提供更多功能,以便以结构化方式构建更复杂的软件。这些工具的许多想法至少可以追溯到35年。例如,参见Lisp Machine manual,这里是1984年的版本,章节Maintaining Large Systems

文件的作用

请注意,在普通的Common Lisp中,文件的作用及其语义并不是很复杂。

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

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

答案 1 :(得分:2)

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