define-library
(define-library (name...) declaration...)
どのライブラリもエクスポートしないプログラム構文で、プログラムや他のライブラリがその名前で import するライブラリを定義します。名前は識別子と正確な非負整数のリストで、scheme で始まる名前は予約されています。宣言は次のとおりです:
(export spec...)。spec は識別子か(rename internal external)です;(import import-set...)。ライブラリ本体から見えるもので、ライブラリが何もimportしないときは、importのないプログラムと同じくすべてが見えます;(begin body...);(include "file"...)と(include-ci "file"...)。ファイルの内容を本体に加えます;(include-library-declarations "file"...)。そのファイルにさらに宣言が入っています;(cond-expand (requirement declaration...)...)。cond-expand が選んだ節の宣言です。
本体はそれ自体 1 つのファイルとして変換されます。インポートする側に届くのはエクスポートした名前だけで、それ以外のトップレベルの名前はライブラリの中に閉じるので、プログラムが同じ名前を定義してもかまいません。ライブラリは、インポートするファイルの先頭、その import より前にある define-library 形式の中から探されるか、ファイルとして探されます: (import (geometry point)) は、プログラムを開始したファイルのディレクトリにある geometry/point.sld、なければ geometry/point.scm を読みます。いくつのファイルがインポートしても、ライブラリが実行されるのは最初のファイルがインポートしたときの 1 回だけです。ライブラリは define-syntax のマクロもエクスポートできます: テンプレートが自由に使う名前は、インポートする側がその名前を何に使っていても、ライブラリの中での意味(非公開の名前も含む)になります。
2
専用のファイルに置いたライブラリで、非公開の補助手続きと、別名でのエクスポートを使う例です:
; file: geometry/point.sld
(define-library (geometry point)
(export make-point point-x point-y (rename add point-add))
(import (scheme base))
(begin
(define-record-type point (make-point x y) point? (x point-x) (y point-y))
(define (add a b)
(make-point (+ (point-x a) (point-x b)) (+ (point-y a) (point-y b))))))
(11 22 mine)
ライブラリの非公開の手続きと変数を使うマクロをエクスポートする例です。インポートする側の count! はそれを置き換えません:
; file: stack/macros.sld
(define-library (stack macros)
(export push! pushes)
(import (scheme base))
(begin
(define pushes 0)
(define (count!) (set! pushes (+ pushes 1)))
(define-syntax push!
(syntax-rules ()
((_ x place) (begin (count!) (set! place (cons x place))))))))
((2 1) 2 mine)