% 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
の宣言であるとき、
それらの宣言は同じように結び付けられます。