第14回 慢性的CL勉強会[予習]
久しぶりにCL勉強会の予習。
今回のお題は「The Common Lisp Cookbook – Functions」だそうです。
今回の資料の内容は大体は知っていることだったので、
細かいところを気にしてみることにしました。
– lambdaの話
- 関数を返す関数のコードがCommon LispとSchemeでは結構違う
- 関数型のオブジェクトを作るには特殊形式functionをlambda式に適用する
- lambdaマクロを使うこともできる
CLtL2によると
car部がlambdaであるリストは関数型ではない。
また、いかなるシンボルも関数型ではない。
しかしながら、関数引数を受け付ける標準Common Lisp関数は
シンボルやそのcarがlambdaであるリストを受け入れ、自動的にそれを関数に強制型変換する。
(2.13 関数)
function fn
もしfnがラムダ式であれば、レキシカルクロージャが返される。
(中略)
function特殊形式の結果は、常にfunction型になること<90>を議決した。
(7.1.1 参照)
とあります。
ここまで読んで疑問に思ったんですが、CLtL2には「lambdaマクロ」の存在が載っていません。
それどころか、funcallの説明において
funcall fn &rest arguments
functionはsymbol型かfunction型のみ許されること<90>を議決した。
ラムダ式は、もはや関数の引数として受け付けられない。
つまり、ラムダ式を陽に引数フォームとして記述する際には、
function特殊形式で囲むか、省略形の#’を前置しなければならない。
(7.3 関数の呼び出し)
なんて書いてます。
そうなると「(funcall (lambda (x) x) 3)」のような式はCLtL2的にはエラーとなるんでしょうか。
一方、CLHSにはしっかりとlambdaマクロのことが書いてありました。
This macro could be implemented by:
(defmacro lambda (&whole form &rest bvl-decls-and-body) (declare (ignore bvl-decls-and-body)) `#',form)(Macro LAMBDA )
この定義は分かりやすいですね。
– セルの話
- シンボルは2つのセルをもつ
- 値セル(value cell) => シンボルに束縛された値を持つ
- 関数セル(function cell) => シンボルの(大域)関数束縛の定義を持つ?(*)
(*) function cell – can hold the definition of the symbol’s (global) function binding.
CLtL2で値セルと関数セルの説明を探して見ましたが、見つかりませんでした。
代わりに見つかったのがこんな文章。
シンボルの重要な用途として、プログラムの名前として用いることがある。
処理系作成の上からは、変数の概念を実現するために、シンボルのある種の要素を用いるのが
望ましい場合がしばしばある。symbol-valueおよびsymbol-functionを参照して欲しい。
しかしながら、実現の方法は他にもある。したがって、そうしたありうる要素についてはここでは述べない。
(10章 シンボル)
ちなみに、CLHSの用語集にはvalue cellとfunction cellがしっかりと載っていましたが、
Cookbookとほぼ同じ内容で、これといって目新しいことは見つかりませんでした。
– カリー化
あと、最後に載っているカリー化関数が気になりました。
&restがあるから、引数を複数取れるけど、これってcurry化っていえるんでしょうか…
まあ、それは置いておいて、appendを使ってるあたりがLispっぽくて面白かったです。