Next: , Previous: , Up: iklib expander   [Index]


6.14.5 Local library imports

Local import forms are useful for the following reasons:

  1. They minimize the namespace clutter that usually occurs when many libraries are imported at the top level.
  2. They limit the scope of the import and thus help modularize a library’s dependencies.
  3. They allow conditional importing of libraries, and so importing alternative libraries according to some expand–time test.

Let’s suppose we are constructing a large library and at some point we realize that a procedure needs to make use of some other library to performing a specific task; importing that library at top level makes it available for the entire library. Consequently, even if that library is no longer used anywhere in the code (say when the code that uses it is deleted), it becomes very hard to delete the import without first examiniming the entire library body for potential usage leaks. By locally importing a library into the appropriate scope, we gain the ability to delete the import form when the procedure that was using it is deleted.

Syntax: import ?import-spec ...

This syntax can be used anywhere definitions can occur:

  1. In a script body.
  2. At library’s top–level.
  3. In internal definitions context.

The syntax of the local import form is similar to the import that appears at the top of a library or a script form, and carries with it the same restrictions:

Each ?import-spec can be as defined by R6RS or a symbol representing the name of a module; notice that module import specifications support all the renaming facilities.

In the following example we import a library in the body of a function:

;;; file "alpha.sls"
(library (alpha)
  (export doit)
  (import (vicare))
  (define (doit)
    (fprintf (current-error-port) "From alpha!\n")))

;;; file "beta.sls"
(library (beta)
  (export doit)
  (import (vicare))
  (define (doit)
    (fprintf (current-error-port) "From beta!\n")))

;;; file "program.sps"
(import (vicare)
  (alpha))
(define (do-that)
  (import (beta))
  (doit))
(doit)
(do-that)
-| From alpha!
-| From beta!

In the following example we import bindings from a module in the body of a function:

(import (vicare))

(define (doit)
  (fprintf (current-error-port) "From body!\n"))

(module do-stuff
  (doit)
  (define (doit)
    (fprintf (current-error-port) "From module!\n")))

(define (do-that)
  (import do-stuff)
  (doit))

(doit)
(do-that)
-| From body!
-| From module!

In the following example: if SRFI-13 is available, import string-concatenate from it; otherwise define a custom version of the function.

#!r6rs
(import (vicare)
  (srfi :0))

(cond-expand
 ((srfi :13)
  (import (only (srfi :13)
                string-concatenate)))
 (else
  (define (string-concatenate strs)
    (receive (port getter)
        (open-string-output-port)
      (for-each-in-order (lambda (str)
                           (display str port))
        strs)
      (getter)))))

(display (string-concatenate '("a" "b" "c")))
(newline)
(flush-output-port (current-output-port))

Next: , Previous: , Up: iklib expander   [Index]