Chapter 5

May 27, 2014
Common Lisp

##Optional Parameters

we can use optional arguments in a function, such as:

	(defun foo (a b &optional c d)
	 (list a b c d))

This will result:

(foo 1 2)				-> (1 2 NIL NIL)
(foo 1 2 3)			-> (1 2 3 NIL)
(foo 1 2 3 4)		-> (1 2 3 4)

Besides, we can set default value for a argument:

	(defun foo (a &optional (b 10)) 
	 (list a b))

This will result:

(foo 1 2) 				-> (1 2)
(foo 1)					-> (1 10)

In this example, argument b is set to 10 by default.

We can also know whether a value is set by default or by explicitly.

	(defun foo (a b &optional (c 3 c-supplied-p))
	 (list a b c c-supplied-p))

For example:

(foo 1 2)			-> (1 2 3 NIL)
(foo 1 2 3)		-> (1 2 3 T)
(foo 1 2 4)		-> (1 2 4 T)

Besides, we can use the value of argument which appears earlier in the argument list:

(defun foo (a &optional (b a))
	(+ a b))

##Keyword Parameters

(defun foo (&key a b c) 
	(list a b c))

function can be invoked as follows:

(foo)						-> (NIL NIL NIL)
(foo :a 1) 			-> (1 NIL NIL)
(foo :b 1)				-> (NIL 1 NIL)
(foo :a 1 :c 3)		-> (1 NIL 3)

Keyword parameters can provide a default value form and the name of a supplied-p value. e.g.:

(defun foo (&key (a 0) (b 0 b-supplied-p) (c (+ a b)))
	(list a b c b-supplied-p))

If you want the keyword the caller uses to specify the parameter to be different from the name of the actual parameter. e.g:

(defun foo (&key ((:apple a)) ((:box b) 0) ((:charlie c) 0 c-supplied-p))
	(list a b c c-supplied-p))

##Mixing Different Parameter Types

Combing &optional and &key parameters yields surprising results. e.g:

(defun foo (x &optional y &key z)
	(list x y z))

It works like this:

(foo 1 2 :z 3) 			-> (1 2 3)
(foo 1)						-> (1 nil nil)
(foo 1 :z 3)				-> ERROR

In the last case, the keyword :z is taken as a value to fill the optional y parameter and leaving only the argument 3 to be processed. So it leads to ERROR.

However, we can combine &rest and &key parameters. e.g:

(defun foo (&rest rest &key a b c)
	(list rest a b c))

you get this result:

(foo :a 1 :b 2 :c 3) 			-> ((:A 1 :B 2 :C 3) 1 2 3)
comments powered by Disqus