moduleのreexport

前回、Chicken Schemeのモジュールについて記事を書きましたが、
reexportという機能も便利なので紹介したいと思います。

合成モジュール

なるべくモジュールは適切な粒度で作っていきたいのですが、
いざモジュールを作り始めると、使う側のimportが大変になっていきます。

(module util.list ()
  (import chicken scheme)
  (export single?)
  (define (single? lst)
    (and (pair? lst) (null? (cdr lst)))))

(module util.function ()
  (import chicken scheme)
  (export bind)
  (define (bind . args)
    (lambda (f) (apply f args))))

moduleのimportは、
そのmoduleがexportしているシンボルだけを束縛するため、
必要なmodule全てをimportする必要があります。

(import
  (prefix util.list u:)
  (prefix util.function u:))

(define lst '(1 2 3))
((u:bind lst) u:single?)

モジュールの数が多くなれば多くなるほど、
importが長くなってしまい、importを書く手間が増えてしまいます。

そこで複数のmoduleをまとめて束縛するための合成モジュールを作成します。

reexport

Chicken Schemeにはreexportという合成モジュールを作成する支援機能があります。
reexportはimportの記法で指定した別モジュールのexportシンボルを、
モジュールのexportに追加します。

(module util ()
  (reexport util.list util.function))

これで、moduleを分割して実装しながら、
利用する側は単一の巨大なUtilモジュールがあるかのように使用できます。

(import (prefix util u:))
((u:bind '(A)) u:single?)

感想

module機能は柔軟性が高いため、代表的な記法はあるものの、
ついつい悪用してしまいたい気分になります。