本文介绍了方案R7RS中的负载与包含之间的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Scheme R7RS中,既有 load include 形式.

In Scheme R7RS there is both a load and include form.

包含被描述为:

负载描述为:

这两种形式的基本原理是什么?我认为这是历史性的.两种形式之间在导入语义上有什么区别吗?我看到 load 可以选择包含一个环境说明符,而 include 则没有.并且 include-ci 在使用 load 时没有直接等效项.但是,仅将 load include 进行比较,有什么区别,并且重要吗?

What is the rationale for the two forms? I assume it is historic. Is there any import semantic difference between the two forms? I see that load can optionally include an environment specifier and include doesn't have that. And include-ci has no direct equivalent using load. But comparing load and include alone, what is the difference and is it important?

推荐答案

我认为关键的区别是 include 语法(或者在传统的Lisp术语中,它是一个宏),而 load 是一个函数.用传统的Lisp术语(在Scheme术语中会有一个更正式的定义,我无法胜任),这意味着 include 在宏扩展时起作用,而load 在评估时完成工作.对于具有文件编译器的实现,这些时间可能会非常不同:宏扩展时间发生在文件编译期间,而评估仅发生在加载编译后的文件之后很多.

I think the critical difference is that include is syntax (or in traditional Lisp terms, it is a macro) while load is a function. In traditional Lisp terms (there will be a much more formal definition of this in Scheme terms which I am not competent to give) this means that include does its work at macro-expansion time, while load does its work at evaluation time. These times can be very different for an implementation which has a file compiler: macro-expansion time happens during compilation of files, while evaluation happens only much later, when the compiled files are loaded.

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

So, if we consider two files, f1.scm containing

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

f2.scm 包含

(define bar 2)

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

then if you load, or compile f1.scm it is exactly the same as if you had loaded or compiled a file fe.scm which contained:

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

反过来与 fe.scm 包含的内容相同:

which in turn is the same as if fe.scm contained:

(define foo 1)
(define bar 2)

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

In particular this inclusion of the files happens at macro-expansion time, which happens when the compiler runs: the object file (fasl file) produced by the compiler will include compiled definitions of foo and bar, and will not in any way depend on f2.scm or its compiled equivalent existing.

现在考虑包含以下内容的 f3.scm

Now consider f3.scm containing:

(define foo 1)
(load "f2")

(请注意,我假设(加载"f2")(而不是(加载"f2.scm"))可以加载已编译的文件它,以及源文件(如果不能):我认为这与实现有关).

(note I have assumed that (load "f2") (as opposed to (load "f2.scm")) loads the compiled file if it can find it, and the source file if it can't: I think this is implementation-dependent).

加载此文件的源代码将与加载 f1.scm 相同:将导致定义 foo bar .但是 compiling 该文件不会:它将生成一个已编译的文件,该文件在以后加载时会 尝试加载 f2的源版本或编译版本.scm .如果该文件存在,则在加载时将被加载,其效果将与 include 情况相同.如果它在加载时不存在,则会发生不良情况.编译 f1.scm 不会导致 f2.scm 中的定义被编译.

Loading the source of this file will do the same thing as loading f1.scm: it will cause foo and bar to be defined. But compiling this file will not: it will produce a compiled file which, when it is later loaded will try to load either the source or compiled versions of f2.scm. If that file exists, at load time, then it will be loaded and the effect will be the same as the include case. If it does not exist at load time, bad things will happen. Compiling f1.scm will not cause the definitions in f2.scm to be compiled.

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

Depending on your background it might be worth comparing this to, say, C-family languages. What include does is what #include does: it splices in source files as they are read, and in C (as in many Scheme/Lisp systems) this happens as the files are compiled. What load does is to load code at runtime, which, in C, you would need to do by invoking the dynamic linker or something.

这篇关于方案R7RS中的负载与包含之间的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 04:52