Scheme 建议的';包括防护装置';计划中?

Scheme 建议的';包括防护装置';计划中?,scheme,Scheme,我们都熟悉: #ifndef MY_HEADER_FILE_H #define MY_HEADER_FILE_H ... #endif (if (not (defined? my-file-included)) (begin (define my-file-included #f) ... )) ; include guard 直到最近,我才开始担心两次加载同一个Scheme文件(SICP Scheme解释器实现改变了这一点…) (if (not (defined? my-f

我们都熟悉:

#ifndef MY_HEADER_FILE_H
#define MY_HEADER_FILE_H
...
#endif
(if (not (defined? my-file-included)) 
  (begin
    (define my-file-included #f)
...

)) ; include guard
直到最近,我才开始担心两次加载同一个Scheme文件(SICP Scheme解释器实现改变了这一点…)

(if (not (defined? my-file-included)) 
  (begin
    (define my-file-included #f)
...

)) ; include guard
方案中是否有推荐的模式来模拟“包含防护装置”?它是可移植的,还是最有可能是特定于实现的

(if (not (defined? my-file-included)) 
  (begin
    (define my-file-included #f)
...

)) ; include guard
我目前正在使用
scm
实现,到目前为止,我已经想到了这一点:

(if (not (defined? my-file-included)) 
  (begin
    (define my-file-included #f)
...

)) ; include guard

所以我开始在我所有的文件上粘贴这个图案,但我不能说我非常喜欢这个。此外,
defined?
scm
中的一个关键字,它的参数未被计算:
(defined?my var)
,而它似乎是
guile中的一个正常函数:
(defined?my var)
mit scheme
不会有它。

您可以编写一个宏来检测给定的标识符是否绑定或没有使用
语法case
。请参阅:(它是用日语编写的,但您可以复制并粘贴代码。)尽管它只使用R6RS过程和宏,但在某些实现中可能无法工作。(博客中提到R6RS第10章表达过程的评论。)

(if (not (defined? my-file-included)) 
  (begin
    (define my-file-included #f)
...

)) ; include guard
如果您使用的是R6RS或R7RS实现之一(例如符合Guile的R6RS),那么最好将包含文件作为库并使用
import

(if (not (defined? my-file-included)) 
  (begin
    (define my-file-included #f)
...

)) ; include guard
如果你想做这样的事情:

(if (not (defined? my-file-included)) 
  (begin
    (define my-file-included #f)
...

)) ; include guard
#if __GUILE__
# include "foo.incl"
#else
# include "bar.incl"
#endif
(cond-expand
  (guile ...)
  (else ...))
然后您可以像这样使用
cond expand

(if (not (defined? my-file-included)) 
  (begin
    (define my-file-included #f)
...

)) ; include guard
#if __GUILE__
# include "foo.incl"
#else
# include "bar.incl"
#endif
(cond-expand
  (guile ...)
  (else ...))

注意:
cond expand
是在R7RS和SRFI-0中定义的。

非常感谢Takashi,我将仔细研究这一点
(if (not (defined? my-file-included)) 
  (begin
    (define my-file-included #f)
...

)) ; include guard