% System-Class FUNCTION
System Class FUNCTION
関数functionとは、適切な数の引数を供給することで
実行されるコードを表現したオブジェクトです。
関数は、function 特殊フォームか、
関数へのcoerceか、
関数へのcompileによって生成されます。
関数は、funcallかapplyかmultiple-value-callの
第一引数として使用することによって直接起動できます。
特定可能
function [arg-typespec [value-typespec]]
arg-typespec ::= (typespec*
[&optional typespec*]
[&rest typespec]
[&key (keyword typespec)*])
typespec - 型指定子
value-typespec - 型指定子
リスト形式のfunction型指定子は
宣言でのみ使用することができ、区別されません。
この型の要素は、
arg-typespecによって指定された関数が受け付ける引数の型と、
value-typeによって指定された返却値の型の集まりです。
引数の型のリストには、
&optional, &rest, &key, &allow-other-keysの印を
表すことができます。
この型指定子が提供する&restは実際の各引数の型を表しており、
続く変数の型ではありません。
&keyパラメーターはフォーム(keyword type)のリストとして
指定されなければなりません。
keywordは、呼び出しのときの実際の引数とし指定される
正当なキーワード名のシンボルである必要があります。
これは通常KEYWORDパッケージ内のシンボルですが、
どんなシンボルでも指定できます。
&keyがfunctionの型指定子のラムダリストに
与えられたときは、
その与えられたキーワードパラメーターは
&allow-other-keysが現れてないのであれば
徹底的に調査されます。
&allow-other-keysは、他のキーワード引数が実際に
指定されるかもしれないことを意味しており、
実際に指定されたときでも使用できます。
例えば、関数make-listの型は下記のように表すことができます。
(function ((integer 0) &key (:initial-element t)) list)
value-typeは、多値の型を示すために、
values型指定子を使うことができます。
下記の宣言フォームを考えます。
(ftype (function (arg0-type arg1-type ...) val-type) f)
この宣言のスコープ内にある
全ての(f arg0 arg1 ...)フォームは
下記と同等になります。
(the val-type (f (the arg0-type arg0) (the arg1-type arg1) ...))
これは、もし引数のどれかが指定された型と一致していないか、 返却値が指定した型と一致していなかったときの結果は未定義です。 とくに引数のどれかが正しく型と一致していないときは、 返却値が指定した型であるという保証はありません。
したがって、関数へのftype宣言は関数呼び出しの記述であり、
実際の関数定義に対するものではありません。
下記の宣言フォームを考えます。
(type (function (arg0-type arg1-type ...) val-type) fn-valued-variable)
この宣言の解釈は次のようになります。
宣言のスコープ内では、もしfn-valued-variableの値が
指定した型の引数で呼ばれなかったときの結果は未定義です。
正しく呼び出されたときの返却値の型はval-typeになるでしょう。
変数の型宣言がネストされたときは、 下記のように、暗黙的に型の共通部分が宣言されます。
ftype宣言を考えます。(ftype (function (arg0-type1 arg1-type1 ...) val-type1) f)
(ftype (function (arg0-type2 arg1-type2 ...) val-type2) f)
もしこれらの宣言の両方に効果があるときは、
それらの宣言で囲まれた共通部分内では、
fの呼び出しは下記のようなfの宣言であるかのように扱われます。
(ftype (function ((and arg0-type1 arg0-type2) (and arg1-type1 arg1-type2 ...) ...)
(and val-type1 val-type2))
f)
これは、ひとつを無視するか、
あるいは全てのftypeを有効にするか、
どちらでも許されます。
functionの宣言であるとき、
それらの宣言は同じように結び付けられます。