For Development HEAD DRAFTSearch (procedure/syntax/module):

4.11 Inclusions

Special Form: include filename …
Special Form: include-ci filename …

[R7RS base] Reads filename … at compile-time, and insert their contents as if the forms are placed in the includer’s source file, surrounded by begin. The include form reads files as is, while include-ci reads files in case-insensitive way, as if #!fold-case is specified in the beginning of the file (see Case-sensitivity).

The coding magic comment in each file is honored while reading that file (see Multibyte scripts).

If filename is absolute, the file is just searched. If it is relative, the file is first searched relative to the file containing the include form, then the directories in *load-path* are tried.

Example: Suppose a file a.scm contains the following code:

(define x 0)
(define y 1)

You can include this file into another source, like this:

(define (foo)
  (include "a.scm")
  (list x y))

It works as if the source is written as follows:

(define (foo)
  (begin
   (define x 0)
   (define y 1))
  (list x y))

(Note: In version 0.9.4, include behaved differently when pathname begins with either ./ or ../—in which case the file is searched relative to the current working directory of the compiler. It is rather an artifact of include sharing file search routine with load. But unlike load, which is a run-time operation, using relative path to the current directory won’t make much sense for include, so we changed the behavior in 0.9.5.)

Gauche has other means to incorporate source code from another files. Here’s the comparison.

require (use and extend calls require internally)
  • Both require and include work at compile-time.
  • Require works only in toplevel context, while include can be anywhere.
  • Require reads the file only once (second and later require on the same file becomes no-op), while include reads the file every place it appears.
  • The file is searched from *load-path*. The location of the file require form appears doesn’t matter. (You can add directories relative to the requiring file using the :relative flag in add-load-path, though).
  • Even if the current module is changed by select-module inside the required file, it is only effective while the required file is read. On the other hand, include inserts any S-expressions in the included file to the place include appears, so the effect of select-module persists after include form (Note: Encoding magic comment and #!fold-case/#!no-fold-case are dealt with by the reader, so those effect is contained in the file even with include).
  • It is forbidden to the file loaded by require to insert a toplevel binding without specifying a module. In other words, the file you require should generally use define-module, select-module or define-library. See Require and provide, for further discussion. On the other hand, include has no such restrictions.
load
  • Works at runtime, while include works at compile-time.
  • Works only in toplevel context, while include can be anywhere.
  • The file is searched from *load-path*, except when the file begins with ./ or ../, in which case it is first tried relative to the current directory before being searched from *load-path*.
  • As the case with require, change of the current module won’t persist after load.

Usually, require (or use and extend) are better way to incorporate sources in other files. The include form is mainly for the tricks that can’t be achieved with require. For example, you have a third-party R5RS code and you want to wrap it with Gauche module system. Using include, you place the following small source file along the third-party code, and you can load the code with (use third-party-module) without changing the original code at all.

(define-module third-party-module
  (export proc ...)
  (include "third-party-source.scm"))


For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT