map-closure特許
map-closureが特許出願されているのに気づいた。(USPTO #20080163188)
- http://www.bcl.hamilton.ie/~qobi/map-closure/ - 著者の一人はschemeコンパイラstalinの人
map-closureは、実行中の環境を検査/変更するためのAPIで、クロージャを渡すと、環境を書き換えたクロージャを返す。
(define (set n new) ((call/cc (lambda (c) (map-closure* ;; per-slot (lambda (n1 old) (if (name=? n n1) new old)) ;; per-object (lambda (x) x) c)))
例えば、スライド中にあるこの手続きsetは、一般的なset!を実装している。現在の継続が含んでいる環境を書き換えればset!を実現できる(ここではグローバルな束縛のことは考えない)。
これをネイティブに実装するためには、クロージャはフレームレイアウト情報と構文情報を残したままコンパイルする必要がある。nmoshではシンボルのリネーミングを行うため、名前を比較するためにはidentifierオブジェクトの比較として実装する必要がある。
これが有ると、動作中のプログラムの書き換えを非常に柔軟に行える。でも特許問題が起こると困るので尻込み中。。
syntax-dispatch
代替案として今考えているのは、syntaxオブジェクトをhookして(プログラムの動作中に)全体をリコンパイルする仕組みで、R6RSライブラリを拡張してdispatchable importという枠を新設する。
ここで、dispatchable symbolとは、map-closureのようなconstructで書き換えられる可能性のあるシンボルを指し、コンパイラはdispatchable symbolに対しては定数畳み込みなどの最適化を行わないようにする。
これは、単一のライブラリを複数のバックエンドによって実装することを想定している。たとえば、DirectXとOpenGLで同じAPIを実装したとして、実行中に実装を切り替えるような用途 :
(library (canvas backends directx) (export (dispatch (canvas)) ...) (import ...)) (library (prog) (export body) (import (rnrs) (dispatchable (canvas))) (define (body) (canvas-new) ...)) (import (prog)) (define dx-body (syntax-dispatch body (canvas backends directx))) (define gl-body (syntax-dispatch body (canvas backends opengl)))
Javaのインターフェースに似ている。また、dispatchable-symbolはC言語のvolatileにも似ている。
もし、プログラムをデバッグモードで実行したいなら、全体をdispatchableだと考えて実行するモードをつければ良いだろう。
map-closureと異なりsyntax-dispatchは構文なので、コンパイラはそれを解釈する余地がある。map-closureの場合はそれに渡すクロージャ自体が書き換えられる可能性があるため、非常にダイナミックなコンパイラが必要になってしまう。