ScmObj* について

昨日の commit で &CDR (foo) とかやってるところに突っ込まれた。
同様のコードが qquote_internal() にもあります。他にはありません。わざわざ出現位置を把握しているのは自分でも変更しなくては、と思っていたから。でもうまいやり方を思いつかずにしばらく放置状態になってました。とりあえず頭にある案を書いておきます。何か思うところがあれば是非。
問題は (見たら分かるでしょうが) リストを先頭から構築する際に、逆向きに作って後から reverse するのではメモリが無駄。かと言ってそこら中に "if (!NULLP(lst)) をばら撒くのはバグの元 + 読みにくい + 遅い、ということです。そこで考えたのは:

ScmObj * を location として認めてしまい、左辺値として使う

当然の如く、API を破ってしまいます。SET() マクロを作れば抽象化として十分だと思うんですが、太田さんが ScmObjInternal をどのように圧縮するつもりか不透明なので保留しています。この方法だと lookup_frame() が location を返すようにすることで、閉包の呼び出しを思いっ切り簡略化 + 高速化できます。できればこれがいい。私とヤマケンさんで圧縮も含めてやってしまうということもできますが。

ScmObjInternal を stack 上に置いて、それで bootstrap する。

Internal じゃなくなります。よろしくない。それと、わかりにくい。SigScheme 外部にこの手を使わせるわけにはいかない。これ用のマクロを用意するか、SCM_ENTYPE_CONS (&head) という本末転倒なコードを書くことになる。GC mark bitmap を使うなら、最初の object が外に流出しないように気を付ける必要がある。そのうち返すときに CDR 取るのを多分忘れる。

最初の一個だけ無駄に cons してそれで bootstrap

そんな妥協は許しまへん。

List constructor をマクロで書く。

例えばこんな感じ。例によってマクロの名前が思いつきません。実装方法によりますが、問題の performance 部分が解決されません。Ad hoc。リスト構築以外で似たような問題が発生すると対応できない。

ScmObj f()
{
  list_ctor ret;
  LIST_CTOR_INIT (ret);
  ...
  for (foo; bar; baz)
    LIST_CTOR_APPEND (ret, obj);
  ...
  return LIST_CTOR_FIN (ret);
}