gpt4 book ai didi

scheme - Scheme R7RS中load和include的区别

转载 作者:太空宇宙 更新时间:2023-11-03 18:43:23 28 4
gpt4 key购买 nike

在 Scheme R7RS 中,有 loadinclude 两种形式。

包含描述为:

Semantics: Both include and include-ci take one or more filenames expressed as string literals, apply an implementation-specific algorithm to find corresponding files, read the contents of the files in the specified order as if by repeated applications of read, and effectively re- place the include or include-ci expression with a begin expression containing what was read from the files. The difference between the two is that include-ci reads each file as if it began with the #!fold-case directive, while include does not. Note: Implementations are encouraged to search for files in the directory which contains the including file, and to provide a way for users to specify other directories to search.

负载描述为:

An implementation-dependent operation is used to trans- form filename into the name of an existing file con- taining Scheme source code. The load procedure reads expressions and definitions from the file and evalu- ates them sequentially in the environment specified by environment-specifier. If environment-specifier is omitted, (interaction-environment) is assumed. It is unspecified whether the results of the expres- sions are printed. The load procedure does not af- fect the values returned by current-input-port and current-output-port. It returns an unspecified value. Rationale: For portability, load must operate on source files. Its operation on other kinds of files necessarily varies among implementations.

这两种形式的基本原理是什么?我认为这是历史性的。这两种形式之间是否存在任何导入语义差异?我看到 load 可以选择包含环境说明符,而 include 没有。并且 include-ci 没有使用 load 的直接等价物。但是单独比较loadinclude,有什么区别,重要吗?

最佳答案

我认为关键的区别在于 includesyntax(或者用传统的 Lisp 术语来说,它是一个宏)而 load 是一个功能。在传统的 Lisp 术语中(在 Scheme 术语中会有更正式的定义,我无力给出)这意味着 include 在宏扩展时完成它的工作,而 load 在评估时完成它的工作。对于具有文件编译器的实现,这些时间可能非常不同:宏扩展时间发生在文件编译期间,而评估仅在很晚的时候发生,当编译的文件被加载时。

因此,如果我们考虑两个文件,f1.scm 包含

(define foo 1)
(include "f2.scm")

f2.scm包含

(define bar 2)

然后,如果您加载、或编译 f1.scm 它与加载或编译文件 fe.scm 完全相同> 其中包含:

(define foo 1)
(begin
(define bar 2))

这又等同于 fe.scm 包含:

(define foo 1)
(define bar 2)

特别是文件的包含发生在宏扩展时,这发生在编译器运行时:编译器生成的目标文件(fasl 文件)将包含 foobar,并且不会以任何方式依赖于 f2.scm 或其已编译的等效项。

现在考虑 f3.scm 包含:

(define foo 1)
(load "f2")

(请注意,我假设 (load "f2")(与 (load "f2.scm") 相对)如果可以找到则加载已编译的文件它,如果不能的话还有源文件:我认为这取决于实现)。

加载此文件的源代码与加载 f1.scm 执行相同的操作:它将导致定义 foobar .但是编译这个文件不会:它会生成一个编译文件,稍后加载时会尝试加载 f2 的源版本或编译版本。单片机。如果该文件存在,则在加载时将加载该文件,效果与 include 情况相同。如果它在加载时不存在,就会发生不好的事情。编译 f1.scm 不会导致编译 f2.scm 中的定义。


根据您的背景,可能值得将其与 C 系列语言等进行比较。 include 所做的就是#include 所做的:它在读取源文件时拼接它们,而在 C 中(如在许多 Scheme/Lisp 系统中),这发生在文件中被编译。 load 的作用是在运行时 加载代码,在 C 语言中,您需要通过调用动态链接器或其他方式来加载代码。

关于scheme - Scheme R7RS中load和include的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48404418/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com