在C中,为了确保我们不会重新包含所包含的标题,我们使用以下结构:
#ifndef UTILS
#define UTILS
#include "my_utils.h"
#endif
我把我的Lisp程序分成了不同的文件;多个文件有时使用相同的文件(例如,多个文件使用my_utilities)。当我运行程序时,我收到警告,我正在重新定义事物(多次调用同一文件的load
)。
这可以通过在C中执行类似于#ifndef
的操作来解决。什么是Common Lisp等效或标准方法?
我是Lisp的新手。让我知道我是否缺少最佳实践(也许是构建我的程序的不同方法?)。
答案 0 :(得分:7)
C中#if
之类的预处理器条件的直接模拟是
#+
读取时间条件化工具。
为避免多次加载文件,您可以使用标准
(但已弃用)
provide
/require
设施,
或像ASDF这样的附加系统。
答案 1 :(得分:6)
对于Common Lisp应用程序和库,最好使用 system 管理工具。像ASDF或您的实施可能提供的任何内容。系统是具有依赖关系和各种操作(加载,编译,...)的文件的集合。
您始终可以检查运行时的状态并执行某些操作。
示例:
(unless (fboundp 'foobar)
(require "foo")
(load "bar"))
(unless (find-package 'foobar)
(require "foo")
(load "bar"))
PROVIDE
和REQUIRE
就是内置函数。如果您需要模块,则会加载它,除非已经provided
。遗憾的是,标准中未详细说明此功能,但实现可能会提供有用的功能。
Common Lisp运行时在列表*features*
上有一个功能列表。您可以使用它来宣传和检查功能。
示例:
在你的图书馆:
(push :cool-new-graphics-library cl:*features*)
在您的应用程序代码中:
(when (member :cool-new-graphics-library cl:*features*)
(funcall (find-symbol "DRAW-SPACE-SHIP" "CNGL")
:death-star))
Common Lisp提供了一种条件化读取时间的方法。仅当:cool-new-graphics-library
功能存在时才会读取以下代码,因此只会在以后执行:
#+cool-new-graphics-library(cngl:draw-space-ship :death-star)
Common Lisp也允许你表达一些逻辑:
#+(and lispworks cool-new-graphics-library)
(cngl:draw-space-ship :enterprise)
#-cool-new-graphics-library(warn "no cool graphics library available")
请注意,您可以强制Lisp在编译时执行代码:
(eval-when (:load-toplevel :compile-toplevel :execute)
#+(and lispworks cool-new-graphics-library)
(cngl:draw-space-ship :enterprise)
#-cool-new-graphics-library(warn "no cool graphics library available")
)
要使其工作,EVAL-WHEN
必须位于文件的顶层。这意味着它无法在嵌套表单中深入工作。但它确实在顶级PROGN
,LOCALLY
,MACROLET
和SYMBOL-MACROLET
内工作。
因此EVAL-WHEN
允许您运行代码,该代码是当前编译的文件的一部分。此代码可以查找已加载的系统,提供的模块,可用的功能等。