定义函数

;;; 辅助变量(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)))

;;; 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