インラインライブラリの使い途
prev : http://d.hatena.ne.jp/mjt/20100513/p1
インラインライブラリ、つまり、スクリプト中で異なるname spaceを利用することのメリットはいくつか考えられる。
同一言語を利用するケース
R6RSには、マクロ展開で利用する手続きを簡単に定義するポータブルな手法が存在しない。
つまり、
(define (my-translator x) ...) (defmacro hoge (^f (my-translator f)))
のようなスクリプトはR6RSの範囲内では書けない。defineでrunフェーズに対して定義した手続きをマクロ展開中に使いたいケース。
実は、psyntax-moshはこのような記述を許可しているが、nmoshは許可していないという違いがある。
これを、R6RSポータブルに書くためには、my-translatorを分離し、別のライブラリとして記述した上で別途importする必要がある。(このため、moshのshortenライブラリはlisp-translatorを別のライブラリ(shorten helper)中に宣言している。)
(library (helper) (export my-translator) (import (rnrs)) (define (my-translator x) ...)) (import (rnrs) (for (helper) expand)) (defmacro hoge (^f (my-translator f)))
実際には、このようにライブラリに分離するのは(書き捨てプログラムにおいては)単に煩雑であり、もっと手軽に、別のライブラリを記述できるための良い手法を必要としている。
例えば、define-for-expand構文が存在すると仮定して、
(define-for-expand (my-translator x) ...) (defmacro hoge (^f (my-translator f)))
のように書けると良い。
異なる言語を使用するケース
SRE(S式を利用した正規表現)や、yuni(僕が制作している、パケット/ファイル構造記述言語)のようにS式を利用した別のプログラミング言語を取りこもうとする場合、あたかもリテラルのようにそれらの言語を混在記述できると便利になる。
例えば、SREをC言語に変換するような処理系が存在するとして、スクリプト中に記述されたSREを別途抜き出してキャッシュするようなことを可能にしたい。このためには、プログラム中のSREとScheme記述を明確に分離する必要が有る。
これはLINQやE4Xと同様の機構と言える。これらの構文は拡張性を捨ててそれなりにシンプルに纏めている。
課題
例えば、define-for-expandのような構文を用意するとして、define-for-expandのスコープ中の語彙を決定する手法が必要になる。この問題は通常のR6RS Syntax-caseにも存在するが、R6RSでは(rnrs)がimportされているものと仮定し、さらに追加のimportを(for (HOGE) expand)によって追加することができる。
通常のニーズは、"expandフェーズの語彙 == runフェーズの語彙"だろう。しかし、expand自体に非常に時間が掛かるnmoshでは必然的にexpandの結果をキャッシュしなければならないため、そのような仕様にするのは難しい。