Posted 2019-02-23 18:23:58 GMT

たまに、Common Lispの仕様では (lambda (x) ...) を関数の名前として定められている、というような話がされることがあります。

しかし、結論としては、ANSI Common Lisp規格では関数の名前ではありません。

今回は、その辺りを調べてまとめてみました。

ANSI Common Lisp規格での関数の名前

(lambda (x) ...) は、ANSI Common Lisp規格では、lambda expressionと呼びますが、その説明を読むとfunction nameが位置する場所にある lambda から始まるリスト、のように持って回った説明がされています。

とりあえず、lambda expressionの方は置いておいて、function nameの方を確認すると、シンボルもしくは、 (setf シンボル) というリストがfunction nameとなっています。

Common Lisp(1984)での関数の名前

しかし、CLtL1でお馴染のCommon Lisp(1984)での記述を確認してみると、ANSI規格に比べると記述は曖昧で、関数名としてのシンボルと、ラムダ式を同一視しているような記述ではありました。

CLtL1: 5.2 Functions

There are two ways to indicate a function to be used in a function call form. One is to use a symbol that names the function. This use of symbols to name functions is completely independent of their use in naming special and lexical variables. The other way is to use a lambda-expression, which is a list whose first element is the symbol lambda . A lambda-expression is not a form; it cannot be meaningfully evaluated. Lambda-expressions and symbols, when used in programs as names of functions, can appear only as the first element of a function-call form, or as the second element of the function special form. Note that symbols and lambda-expressions are treated as names of functions in these two contexts. This should be distinguished from the treatment of symbols and lambda-expressions as function objects, that is, objects that satisfy the predicate functionp , as when giving such an object to apply or funcall to be invoked.

これはANSI規格へ向けての中間報告であるCLtL2(1990)でも同様です。

この記述をうけてか、竹内郁雄先生の1980年代の著作である「初めての人のためのLisp」11章の脚注にもこんな記述があります。

Common Lispではこのリストを，関数実体を表わす一種の"名前"と呼んでいます。

ちなみに、増補改訂版(2010)では、脚注から本文の先生の台詞に昇格して

Common Lispではこのリストを，関数実体を表わす一種の"名前"であるとしておる

となっています。 まあ、「一種の“名前”」となっているので、どうとでも解釈できそうです。

Common Lisp(1984)からANSI Common Lisp(1994)までに何が変化したのか

ANSI Common Lisp(1994)は、オブジェクト指向システムやコンディションシステムの追加等が目立つところですが、それまで曖昧だった概念や記述が大分整理されました。

function nameとlambda expressionが分離した背景については、Issue FUNCTION-NAME Writeupに記録があります。

まず、function nameについての整理があり、 function 、 fdefinition 、 defun 、 fboundp 、 fmakunbound 等々、関数の名前を取るものの整理がされ、 (setf ...) が新しく関数名とされました。

これを推進して、lambda expressionを関数名として扱うかの提案が、 FUNCTION-NAME:LARGE の12番にあります。

12. Declare that any lamba expression (i.e., a list whose car is LAMBDA and whose cdr is a well-formed lambda argument list and body) is a function name.

lambda expressionが名前となれば、

( fmakunbound ( lambda ( ) ... ) )

のようなケースも考えていくことになると思うのですが、しかし、結局、lambda expressionが無名関数を表す慣習からすると、それをもって名前とするのは矛盾としています。

名は体を表すといいますが、lambda expressionは体が体を表してしまっているというところでしょうか。

Lambda expressions are often thought to denote "anonymous" functions, so it may seem paradoxical to treat them as names. The paradox is only apparent, since the expression itself has the properties of a Lisp function name: It is (typically) a cons tree which can be read, printed, and stored in source files, and it denotes a well-defined Lisp function.

ここからどのような投票が行なわれ、どう決定されたかの資料はみあたらないのですが、12番の提案は採用されなかったのは確かで、function nameにlambda expressionは含まれることは無かった、ということでしょう。

まとめ

年配の方々はもうしょうがないと思いますが、若者はANSI Common Lisp規格を読みましょう。

また、CLtL2はCLtL1からANSI Common Lispまでの中間報告であり規格ではありませんので、CLtL1/2で得た知識は一度ANSI Common Lisp規格でどう変更された/されていないのかの確認をしましょう。

■

