第3回 慢性的CL勉強会[まとめ]

Lingrのログはこちら。
*疑問への回答*
今回も予習した内容に返答をもらえました。
ありがとうございます。
– loopマクロって多用するものなの?
多用するらしいです。
loopを使えてこそCLer?
– ignoreとignorable
この二つは変数を使わないときに出る警告を抑えるそうです。
Prologで言うところの、 _(anonymous variable) がignore、
_から始まる変数(underscore variable)がignorableのようです。
(パターンマッチをするわけではないので少々意味が違いますが。)
– #’car と ’car
#’の場合はコンパイル時にオブジェクトが決定されますが、
‘の場合は実行時にシンボルから関数を探すようです(だから#’の方が最適化される)。
fletでローカルな束縛を作っても’だと大域関数になるようです。
*その他の事項*
– lexprとかfexpr
「このあたりはzickさんが得意だと思うんですが」と書かれたので一応書いておきます。
昔のLispでは関数は次のように分類されたそうです。
+ subr : いわゆる組み込み関数。恐らくsubroutineの略。引数の数は固定
+ fsubr : 引数を評価しない組み込み関数。関数というよりむしろスペシャルフォーム。
+ lsubr : 引数の数が可変長の組み込み関数。引数は評価される。
+ expr : lambdaで作る関数。expressionの略という噂を聞いた。
+ fexpr : 引数を評価しないユーザ関数。マクロに近い。
+ lexpr : 引数の数が可変長のユーザ関数。引数は評価される。
fexprはnlambdaというスペシャルフォーム(fsubr?)で作ります。
lexprは確かlambdaで特殊な書き方をしたら作れたかと思います(これは自信がない)。
またexpr系統の関数をコンパイルすればsubr系統として扱われたかと思います。
このあたりの内容は
中西 正和 (著) 『Lisp入門―システムとプログラミング』
に全て書いてあります。興味がある方はこちらをご覧下さい。
ちなみに、私はこれを最初に学んだので、私の作った処理系(例えば地獄Scheme)
では、スペシャルフォームを作る関数がCreateFEXPRという名前だったり、
スペシャルフォームとしてnlambdaがあったりして、それで一部のスペシャルフォームを作っています。
*Lispマシンといえば*
今回の勉強会では話題に上がってなかったみたいですが、
Lispマシンといえば私はCDRコーディングを思いつきます。
CDRコーディングとはリストの要素がメモリ上で連続して配置してある際に、
メモリを節約する技術のことです。
(恐らく)多くのLispではCAR部とCDR部をセットにしたもの(ポインタ2つ分)をコンスセルとしますが、
CDRコーディングを用いる場合は、この半分のもの(ポインタ1つ分)を1つのセルとして扱います。
リストの要素がばらばらに配置されている場合はCAR部の次にはCDR部が配置されますが、
要素が連続している場合はCDR部ではなく次のコンスセルのCAR部を配置します。
こうすることによりメモリ使用量を減らせる上にキャッシュのヒット率も上がるという魂胆です。
これを実現するためには
「次のセルは現在のセルのCDR部(通常のコンスセル)」
「次のセルは次のセルのCAR部で、これが現在のセルのCDR部の参照先」
「現在のセルのCDR部はNIL」
「現在のセルは現在のセルが指す先にある(間接参照)」
の4つの状態を考える必要があるために2ビットを消費します。
(最後の一つはCAR部, CDR部を書き換えたときの対策です)
私もCで作った自作のLispインタプリタでCDRコーディングをやってみようかと思ったんですが、
CDRコーディングに2ビットもとられると1語32ビットに1つのセルを入れるのがなかなか辛くて、
どうしたものかと考えてみて、実際にCDRコーディングをしているSymbolic3600を見てみると、
このマシンは1語が36ビットあるから余裕だったようです。
これが……専用マシンか、と少し悔しくなりました(笑)

Leave a Reply