実装言語と被実装言語の界面

(一応、他人のツイートを見て思いついたことなのですが、元のツイートではどちらかというとインタラクティブな環境を実現することに主眼がある感じで、ここに書く話ではそれには触れないのでそのへんは省略します)
Lispの評価器(インタプリタ)をLispで書く、いわゆる超循環評価器では、実装言語と被実装言語の界面は存在してはいるものの、見た目、かなり混沌とした感じになります( SICP のそれのようにきちんと抽象化して書けば整理されるはずではありますが)。少し前に、ポールグレアムさんが書かれたもの( http://ep.yimg.com/ty/cdn/paulgraham/jmc.lisp )などを参考にあれこれいじってみていたのですが、たとえば Gauche で実装していて、被実装言語の空リストと真偽値をシンボル nil と t で表現するようにしたりしていたところ、自分でも混乱して、時々謎なバグを入れ込んでしまったりしました(特に、さらに超循環評価器の入れ子を作る時に。実際には2段目から先は一種の不動点になります)。
これを、Lisp(含む方言)で書くにしても、SICP や Three Implementation Models for Scheme にあるように仮想機械的な命令列にコンパイルして解釈実行(インタプリット)するようにすれば少しは変わりますが、やはり本格的には、(静的な)型システムのある言語で書くべきでしょう。
zick さんの記事( http://blog.bugyo.tk/lyrical/archives/1877 )にあるように、バリアント型のような型で Lisp の任意のアトムと2ツ組を表現することになるでしょう(Haskellでそのうち...)。
すると、実装言語と被実装言語の界面が明確になります。一例として (+ (+ 1 2) (+ 3 4) 5) というような式を評価していて、最後の + の本体を呼ぶ直前には[3, 7, 5]というような引数のリストができているわけですが、ここで、このリスト自体は実装言語(たとえばHaskell)のネイティブなリストを使うでしょうし、一方その要素は前述の、被実装言語のデータを表現するための型になるわけです。