For Gauche 0.9.15Search (procedure/syntax/module):

Next: , Previous: , Up: Core library   [Contents][Index]

6.22 Loading Programs


6.22.1 Loading Scheme file

Function: load file :key paths (error-if-not-found #t) environment ignore-coding

[R7RS+ load] Loads file, that is, read Scheme expressions in file and evaluates them. An extension “.scm” may be omitted from file.

If file doesn’t begin with “/” or “./” or “../”, it is searched from the system file search list, stored in a variable *load-path*. Or you can explicitly specify the search path by passing a list of directory names to the keyword argument paths.

On success, load returns the string pathname of the file actually loaded. If the specified file is not found, an error is signaled unless the keyword argument error-if-not-found is #f, in which case load returns #f.

By default, load uses a coding-aware port (see Coding-aware ports) so that the "coding:" magic comment at the beginning of the source file is effective. (See Multibyte scripts, for the details of the coding magic comment). If a true value is given to the keyword argument ignore-coding, load doesn’t create the coding-aware port and directly reads from the file port.

If a module is given to the keyword argument environment, load works as if the given module is selected at the beginning of the loaded file.

The current module is preserved; even select-module is called in file, the module in which load is called is restored afterwards.

Gauche’s load is upper-compatible to R5RS load, but R7RS load differs in optional arguments; see scheme.load - R7RS load.

If you want to load a library file, it’s better to use ‘use’ (see Defining and selecting modules), or ‘require’ described below. See Compilation, for difference between load and require.

Variable: *load-path*

Keeps a list of directories that are searched by load and require.

If you want to add other directories to the search path, do not modify this variable directly; use add-load-path, described below, instead.

Special Form: add-load-path path flag …

Adds a path path to the library load path list. Path must be a literal string, for load paths must be known at compilation time. If path is a relative path, it is resolved relative to the current working directory, unless :relative flag is given.

Path doesn’t need to exist; nonexisting paths in load path list are simply ignored. However, if path does exist, add-load-path searches for architecture-dependent paths; see below.

Each flag argument may be one of the followings.

:after

Append path to the end of the current list of load paths. By default, path is added in front of the load path list.

#t

The same as :after. This is for the backward compatibility.

:relative

Interpret path as a relative path to the directory of the current file, instead of the current working directory. If the current file can’t be determined (e.g. evaluated in REPL, or the expression is read from a socket), this flag is ignored.

Use this form instead of changing *load-path* directly. This form is a special form and recognized by the compiler; if you change *load-path*, it is in effect at run time, and that may be too late for “use” or “require”.

Furthermore, add-load-path looks for the architecture dependent directories under the specified path and if it exists, sets up the internal path list for dynamic loading correctly. Suppose you have your Scheme module in /home/yours/lib, and that requires a dynamic loadable library. You can put the library under /home/yours/lib/ARCH/, where ARCH is the value (gauche-architecture) returns (see Environment inquiry). Then you can have compiled libraries for multiple platforms and Gauche can still find the right library.

Function: load-from-port port

Reads Scheme expressions from an input port port and evaluates them, until EOF is read.

Note that unless you pass a coding-aware port to port, the "coding:" magic comment won’t be handled.

Function: current-load-port
Function: current-load-path
Function: current-load-history
Function: current-load-next

These procedures allows you to query the current context of loading. They returns the following values when called inside a file being loaded:

current-load-port

Returns the port object from which this form is being loaded.

current-load-path

Returns the pathname of the file from which this form is being loaded. Note that this may return #f if the source of load is not a file.

current-load-history

Returns a list of pairs of a port and a line number (integer), representing the nesting of loads. Suppose you load foo.scm, and from its line 7 it loads bar.scm, and from its line 18 it loads baz.scm. If you call current-load-history in the file baz.scm, you’ll get

((#<port "foo.scm"> . 7) (#<port "bar.scm"> . 18))
current-load-next

Returns a list of remaining directories to be searched at the time this file is found. Suppose the *load-path* is ("." "../lib" "/home/gauche/lib" "/share/gauche/lib") and you load foo.scm, which happens to be in ../lib/. Then, inside foo.scm, current-load-next returns:

("/home/gauche/lib" "/share/gauche/lib")

When called outside of load, these procedures returns #f, #f, () and (), respectively.


6.22.2 Load dynamic library

Function: dynamic-load file :key init-function

Loads and links a dynamic loadable library (shared library) file. File shouldn’t contain the suffix (“.so” on most systems); dynamic-load adds it, for it may differ among platforms.

The keyword argument init-function specifies the initialization function name of the library in a string. By default, if the file basename (without extension) is “foo”, the initialization function name is “Scm_Init_foo”.

Usually a dynamic loadable library is provided with wrapping Scheme module, so the user doesn’t have to call this function directly.

There’s no way to unload the loaded libraries.


6.22.3 Require and provide

Require and provide are a traditional Lisp way to ensure loading a library file only once. If you require a feature for the first time, a library file that provides it is loaded and the fact that the feature is provided is memorized. Subsequent request of the same feature doesn’t need to load the file.

In Gauche, the use syntax (see Using modules) hides the require mechanism under the hood so you hardly need to see these forms. These are provided just in case if you want to do some non-trivial management of libraries and thus want to bypass Gauche’s standard mechanism.

Special Form: require feature

If feature is not loaded, load it. Feature must be a string, and it is taken as a file name (without suffix) to be loaded. This loading takes place at compile time.

If you load SLIB module, require is extended. see slib - SLIB interface for details.

If the loaded file does not contain provide form at all, the feature is automatically provided, as if (provide feature) is called at the end of the loaded file. We call this autoprovide feature.

Note that require first sets the current module to an immutable module called gauche.require-base and then load the file. The files loaded by require usually have define-module/select-module or define-library for the first thing, so you rarely notice the gauche.require-base module. However, if the loaded file has toplevel defines or imports (use’s) without specifying a module, you’ll get an error like the following:

*** ERROR: Attempted to create a binding (a) in a sealed
module: #<module gauche.require-base>

Rationale: Generally it’s difficult to guarantee when the specified file is loaded by require (because some other module may already have required it). If we just used the caller’s current module, there would be a couple of issues: The form define-module or define-library may not be visible from the current module, and you can’t guarantee if the toplevel defines without specifying modules in the loaded file inserts the caller’s current module, since they may have been loaded into a different module. It is just a bad idea to insert toplevel definitions or to import other modules without specifying which module you put them in. So we made them an error.

Function: provide feature

Adds feature to the system’s provided feature list, so that the subsequent require won’t load the same file again.

Because of the autoproviding, i.e. require automatically provides the required feature, you hardly need to use a provide form explicitly. There are a couple of scenarios that you may want to use a provide form:

  • To provide a feature (or features) that is/are different from the one that caused loading the file.

    Suppose feature X supersedes feature Y and providing compatible APIs of Y but with different implementation. Once X.scm is loaded, you don’t want Y.scm to be loaded; so you want to tell the user that X.scm also provides the feature Y. Adding (provide "X") and (provide "Y") at the end of X.scm accomplish that. (Note: If you add a provide form, require no longer autoprovides the feature, so you need to specify (provide "X") in X.scm explicitly to provide X as well.)

    Of course, this doesn’t prevent users from loading Y.scm by specifying (require "Y") before (require "X"). It should be considered just as a workaround in a production where other solutions are costly, instead of a permanent solution.

  • To provide no features at all. Passing #f as feature prevents autoproviding by require without providing any feature.

    This should also be a temporary solution. One possible scenario is that you are changing X.scm very frequently during development and you want (require "X") always causes loading the file. Don’t forget to remove (provide #f) when you release the file, though. Besides, for interactive reloading, consider using gauche.reload (see gauche.reload - Reloading modules) instead.

Function: provided? feature

Returns #t if feature is already provided.


6.22.4 Autoload

Macro: autoload file/module item …

Sets up item … to be autoloaded. That is, when an item is referenced for the first time, file/module is loaded before the item is evaluated. This delays the loading of file/module until it is needed.

You can specify either a string file name or a symbol module name to file/module. If it is a string, the named file is loaded. If it is a symbol, the named module is loaded (using the same rule as of use), then the binding of item in the file/module is imported to the module used the autoload (See Defining and selecting modules, for details of use).

Item can be either a variable name (symbol), or a form (:macro symbol). If it is a variable, the named file/module is loaded when the variable is about to be evaluated. If it is the latter form, the named file/module is loaded when a form (symbol arg …) is about to be compiled, which enables autoloading macros.

file/module must define symbol in it, or an error is signaled when file/module is autoloaded.

The following is an example of autoloading procedures.

(autoload "foo" foo0 foo1)
(autoload "bar" bar0 bar1)

(define (foobar x)
  (if (list? x)
      (map bar0 x)
      (foo0)))

(foobar '(1 2)) ; "bar" is loaded at this moment

(foobar #f)     ; "foo" is loaded at this moment

Note that if you set to autoload macro, the file/module is loaded immediately when such form that uses the macro is compiled, regardless of the piece of the code is executed or not.


Previous: , Up: Loading Programs   [Contents][Index]

6.22.5 Operations on libraries

There are several procedures you can use to check if certain libraries and/or modules are installed in the system.

In the following descriptions, pattern is either a symbol or a string. If it is a symbol, it specifies a module name (e.g. foo.bar). If it is a string, it specifies a partial pathname of the library (e.g. "foo/bar"), which will be searched under library search paths. You can also use glob-like metacharacters * and ? in pattern.

Function: library-fold pattern proc seed :key paths strict? allow-duplicates?

A basic iterator for library/module files. This procedure searches Scheme program files which matches pattern, under directories listed in paths (the default is the standard file load paths, *load-path*). For each matched file, it calls proc with three arguments: the matched module or library name, the full path of the program file, and the state value. Seed is used as the initial state value, and the value proc returns is used as the state value for the next call of proc. The value returned from the last proc becomes the return value of library-fold.

If pattern is a symbol and the keyword argument strict? is #t (which is the default), this procedure calls library-has-module? on the files whose name seems to match the given pattern of module name, in order to find out the file really implements the module. It can be a time consuming process if you try to match large number of modules; you can pass #f to strict? to avoid the extra check. If pattern is a string, matching is done only for file names so strict? is ignored.

By default, if there are more than one files that have the same name that matches pattern in paths, only the first one appears in paths is taken. This gives you the file you’ll get if you use require or use for that library. If you want to iterate all of matching files, pass #t to the allow-duplicates? keyword argument.

Here are some examples (the result may differ in your environment).

(library-fold 'srfi.1 acons '())
 ⇒ ((srfi.1 . "../lib/srfi/1.scm"))

(library-fold "srfi.1" acons '())
 ⇒ (("srfi.1" . "../lib/srfi/1.scm"))

;; Note the returned list is in a reverse order of
;; how acons is called.
(library-fold 'srfi.1 acons '() :allow-duplicates? #t)
 ⇒ ((srfi.1 . "/usr/share/gauche-0.98/0.9.13/lib/srfi/1.scm")
   (srfi.1 . "../lib/srfi.1.scm"))

;; Finds available dbm implementations
(library-fold 'dbm.* acons '())
 ⇒ ((dbm.cdb . "/usr/share/gauche-0.98/0.9.13/lib/dbm/cdb.scm")
   (dbm.gdbm . "../lib/dbm/gdbm.scm")
   (dbm.ndbm . "../lib/dbm/ndbm.scm")
   (dbm.odbm . "../lib/dbm/odbm.scm"))
Function: library-map pattern proc :key paths allow-duplicates? strict?
Function: library-for-each pattern proc :key paths allow-duplicates? strict?

Map and for-each version of iterator over matched libraries/modules. See library-fold above for detailed operation of matching and the meanings of keyword arguments.

Proc receives two arguments, the matched module/library name and full path of the file. Library-map returns a list of results of proc. Library-for-each discards the results.

(library-map 'srfi.4 list :allow-duplicates? #t)
 ⇒ ((srfi.4 "../lib/srfi/4.scm")
            (srfi.4 "/usr/share/gauche-0.98/0.9.13/lib/srfi/4.scm"))

(library-map 'dbm.* (lambda (m p) m))
 ⇒ (dbm.odbm dbm.ndbm dbm.gdbm dbm.cdb)
Function: library-exists? mod/path :key paths force-search? strict?

Search a library or a module specified by mod/path, and returns a true value if it finds one. Paths and strict? keyword arguments have the same meaning as library-fold.

Unlike the iterator procedures above, this procedure first checks loaded libraries and modules in the calling process, and returns true if it finds mod/path in it, without looking into the filesystem. Passing #t to force-search? keyword arguments skips the checking of loaded libraries and modules.

Function: library-has-module? path module

Returns #t iff a file specified by path exists and appears to implement a module named by module. path must be an actual filename.

(library-has-module? "./test/foo/bar.scm" 'foo.bar)
 ⇒ #t ;; if ./test/foo/bar.scm implements module foo.bar.

This procedure assumes a typical layout of the source code to determine if the given file implements the module, i.e., it reads the first form of the code and see if it is a define-module form that is defining the given module.


Next: , Previous: , Up: Core library   [Contents][Index]


For Gauche 0.9.15Search (procedure/syntax/module):