続 R6RS Records

MoshR6RS Records に関するバグ指摘があって調べていた。仕様を正しく理解していなかったのが原因。
仕様は理解できたのだが実装できる気がしない。Mosh は Records の Procedural レイヤを C++ で書いているのだが、3 つのレコードが継承関係にあるときの protocol の実装とかが面倒。

というわけで r6rs.org にある Scheme で書かれた参照実装を移植することにした。(正確には Ypsilon に移植されたものを移植)。
Records は例外のコンディションの下支えでもあるので移植と移行は大変だったが実装はすっきりした。


C++ で実装したくない例。手続きを返す手続きを返す手続きを返すを返すの中に loop の再帰がある。

(lambda (desc rtd argc)
    ((rcd-protocol desc)
     ((let loop ((desc desc))
        (cond ((rcd-parent desc)
               => (lambda (parent)
                    (lambda extra-field-values
                      (lambda protocol-args
                        (lambda this-field-values
                          (apply ((rcd-protocol parent)
                                  (apply (loop parent)
                                         (append this-field-values extra-field-values)))
                                 protocol-args))))))


ちなみに Records が複雑なのは Condition に使うためなのだが、R6RS コードでコンディションの継承関係を利用して例外をきっちりハンドルしているコードは見た事無い。