これまでは、すでに Common Lisp の仕様で定められた標準関数を利用してきましたが、開発者が独自の関数を定義することも可能です。 Lisp 言語によるプログラミングでは、既存の関数の処理を組み合わせてより複雑な関数を構築し、さらにそれを組み合わせていくことで目的のプログラムを作っていくことになります。
新しい関数を定義するには defun マクロを使います。 このマクロが評価された時点で、新しく定義した関数が有効になります。
defun function-name lambda-list form*
function-name には、新しく定義する関数の名前を指定します。 lambda-list は、呼び出されるときにリストから関数に渡される仮パラメータを指定します。
lambda-list はラムダリストとも呼ばれ、ここにはパラメータとなる変数を指定します。 この変数は評価されずに、関数の呼び出し元から指定されたデータを格納するためのものです。 関数が特に値を受け取らない場合は空のリスト ( ) を指定します。
最後の form は、新しく定義する関数の本体になる部分で、任意の数の式を記述することができます。 関数を定義した後、関数が呼び出されると form が実行されます。
defun マクロの実行結果は常に関数名 function-name に指定した記号となります。 すでに定義されている関数名が指定された場合、既存の関数から新しい定義に上書きされます。 関数の定義に誤りがあった場合は、後から内容を書き直すことができるのです。 ただし、特別式に指定されている名前 setq などを定義することはできません。
> (defun test () 10) TEST > (test) 10 > (defun add (a b) (+ a b)) ADD > (add 10 20) 30
最初に定義している test 関数は、何も値を受け取らずに常に 10 という結果を返す単純な関数です。 defun で定義した後 (test) によって test 関数を呼び出すと、正しく 10 が帰っていることがわかります。
その次の add 関数は、呼び出し時にパラメータとして数値型の a と b を要求しています。 add 関数は、単純に与えられた引数で加算処理を行う + 関数を間接的に実行しているだけです。 結果を見れば、a と b に指定した値を加算した値が返されていることがわかります。
defun て定義された関数は、式を順番に実行し、最後に実行された式の結果を返すということになっています。 そのため、本体の式が複数個設定されている場合は、先頭から順に式を評価して、最後に評価された式の結果を返すことになります。 多くの場合、関数は複数の式から作られることになるでしょう。
> (defun test (x y z) (setq l nil) (setq l (cons x l)) (setq l (cons y l)) (setq l (cons z l)) ) TEST > (test 10 20 30) (30 20 10)
このプログラムでは、与えられたパラメータ x、y、z を用いてリストを返す test 関数を作っています。 test 関数は空の変数 l を作成し、この変数の先頭に x、y、z の値をリストとして挿入しています。 その結果、(10)、(20 10)、(30 20 10) という形でリストが推移し、結果として (30 20 10) というリストが返されています。