(rontolisp) docs
← 構文

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)