第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 cellfunction cellがしっかりと載っていましたが、
Cookbookとほぼ同じ内容で、これといって目新しいことは見つかりませんでした。
– カリー化
あと、最後に載っているカリー化関数が気になりました。
&restがあるから、引数を複数取れるけど、これってcurry化っていえるんでしょうか…
まあ、それは置いておいて、appendを使ってるあたりがLispっぽくて面白かったです。

Leave a Reply