関数::CommonLisp

  • defun式以外での関数の定義の仕方。
  • 名前の無い関数。
  • 局所的に使われる関数。
  • 関数を呼び出すための関数。

6.2 局所関数

fletは式1...式nでのみ局所的に使う関数を定義する。
(flet ((関数名1 ラムダリスト1 式...式)
       ...
(関数名1 ラムダリスト1 式...式))
   式1
   ...
   式n)

defunで定義した関数は,どこでも使える大域関数
fletで定義した関数は,スコープの中でのみ使える局所関数

6.3 関数呼び出しのための関数

関数呼び出しのフォームは,呼び出される関数と,
その関数が受け付ける引数の数があらかじめ分かっていないと使えない。
呼び出す関数を計算によって決定したい場合にはapplyやfuncallなどの
関数を呼び出すための関数を使う。

funcall

(funcall '+ 2 3 4)
は2, 3, 4を引数として+という名の関数を呼び出す。
funcallの引数は評価されるから,
(funcall f 2 3 4)
として,fが '+ であれば + という記号で和を計算するし,
fが '* であれば * という記号で積を計算する
CL-USER> (let ((f '+))
    (funcall f 2 3 4))

9

CL-USER> (let ((f '*))
    (funcall f 2 3 4))

24

CL-USER> (defun square (x) (* x x)) ;; 2乗
CL-USER> (defun sum-up (f n &aux (sum 0))
    (dotimes (i n sum)
      (setq sum (+ (funcall f i) sum))))
CL-USER> (sum-up 'square 10) ;; 0から9までの2乗和
285
CL-USER> (sum-up '1+ 10) ;; 1から10までの総和
55

apply

funcallは,呼び出される関数が受け付ける引数の数があらかじめ分かってないと使えない。
そういうときにapplyを使う。
次のapplyは,いずれの式も呼び出される関数に1, 2, 3, 4を引数として渡す
(apply f '(1 2 3 4))
(apply f 1 2 '(3 4))
(apply f 1 2 3 4 nil)

apply, funcallへは,次の物を第一引数としてうけわたすことができる。
  1. 関数名を表す記号
  2. ラムダ式
  3. 関数の定義そのもの
  4. クロージャ

multiple-value-call

(multiple-value-call 関数 式1...式n)
funcallは,各式を評価した値1つだけを引数として使うが,
multiple-value-callは全てを引数として使う。
CL-USER> (funcall #'+ (floor 5 3) (floor 19 5))
4 ;; (+ 1 3)
CL-USER> (multiple-value-call #'+ (floor 5 3) (floor 19 5))
10 ;; (+ 1 2 3 4)
最終更新:2011年10月07日 16:42