函数

Table of Contents

1. 定义函数

;;; 辅助变量(auxiliary variables)
;;; &aux 参数,类似 let*:
(defun auto+1 (n &aux (x (1+ n))) x)
(auto+1 1)                              ; => 2

;;; 调用函数时使用关键字参数,而不是符号,因为关键字参数在 keyword 命名空间中,这样任何 package 里的表达式都可以调用。如:
(make-hash-table :test 'equal)
;;; 而不是 (make-hash-table 'test 'equal)
;;; 示例:
(defun noise (animal)
  (case animal
    (:dog :woof)
    (:cat :meow)
    (:pig :oink)))
;;; 如果写成以下方式,在其他包里的代码无法正常工作,因为这个函数中的如 'dog、'cat 都是从当前包中取得:
(defun noise (animal)
  (case animal
    ('dog :woof)
    ('cat :meow)
    ('pig :oink)))

2. 多值函数

Common Lisp 支持函数返回多个值,通常用 values 和 multiple-value-bind。

values:

(values &rest values)

返回多个值。

(values 'value1 'value2)
;; 输出:
;; VALUE1
;; VALUE2

综合示例:

;;; values:返回多个值
(values 1 2 3)                          ; 返回 3 个值
;; 如果用在函数调用,是取的返回的第一个值:
(+ (values 1 2 3) 2)                    ; => 3

;;; multiple-value-bind,将返回的多个值绑定到符号上,语法:
;;; (multiple-value-bind (symbol*) expression*)
(defun foo () (values 1 2 3))
(multiple-value-bind (a b c) (foo) (print (+ a b c))) ; => 6 6

;;; (multiple-value-list expression),返回的多个值组合成一个列表:
(multiple-value-list (foo))             ; => (1 2 3)

;;; (multiple-value-call function expression*),调用 function,并把 expression 返回的多值作为参数:
(defun foo () (values 1 2 3))
(multiple-value-call #'+ (foo))         ; => 6

2.1. nth-value

(nth-value n form)

form 是一个返回多值的表达式,参数 n 用来指定获得哪一个值,n 从 0 开始计数。

(nth-value 1 (values 'value1 "value2")) ; => "value2"
(nth-value 0 (values 'value1 "value2")) ; => VALUE1

3. 相关函数

3.1. fboundp

判断符号是否绑定了函数,定义如下:

(fboundp name)

示例:

(fboundp '+)                            ; => T
(fboundp 'a)                            ; => NIL