   ## 7. Functions

You saw one example of a function above. Here are some more:

``` > (+ 3 4 5 6) ;this function takes any number of arguments 18 > (+ (+ 3 4) (+ (+ 4 5) 6)) ;isn't prefix notation fun? 22 > (defun foo (x y) (+ x y 5)) ;defining a function FOO > (foo 5 0) ;calling a function 10 > (defun fact (x) ;a recursive function (if (> x 0) (* x (fact (- x 1))) 1 ) ) FACT > (fact 5) 120 > (defun a (x) (if (= x 0) t (b (- x)))) ;mutually recursive functions A > (defun b (x) (if (> x 0) (a (- x 1)) (a (+ x 1)))) B > (a 5) T > (defun bar (x) ;a function with multiple statements in (setq x (* x 3)) ;its body -- it will return the value (setq x (/ x 2)) ;returned by its final statement (+ x 4)) BAR > (bar 6) 13 ```

When we defined `foo`, we gave it two arguments, `x` and `y`. Now when we call `foo`, we are required to provide exactly two arguments: the first will become the value of `x` for the duration of the call to `foo`, and the second will become the value of `y` for the duration of the call. In LISP, most variables are lexically scoped; that is, if `foo` calls `bar` and `bar` tries to reference `x`, `bar` will not get `foo`'s value for `x`.

The process of assigning a symbol a value for the duration of some lexical scope is called binding.

You can specify optional arguments for your functions. Any argument after the symbol `&optional` is optional:

``` > (defun bar (x &optional y) (if y x 0)) BAR > (defun baaz (&optional (x 3) (z 10)) (+ x z)) BAAZ > (bar 5) 0 > (bar 5 t) 5 > (baaz 5) 15 > (baaz 5 6) 11 > (baaz) 13 ```

It is legal to call the function `bar` with either one or two arguments. If it is called with one argument, `x` will be bound to the value of that argument and `y` will be bound to `nil`; if it is called with two arguments, `x` and `y` will be bound to the values of the first and second argument, respectively.

The function `baaz` has two optional arguments. It specifies a default value for each of them: if the caller specifies only one argument, `z` will be bound to 10 instead of to `nil`, and if the caller specifies no arguments, `x` will be bound to 3 and `z` to 10.

You can make your function accept any number of arguments by ending its argument list with an `&rest` parameter. LISP will collect all arguments not otherwise accounted for into a list and bind the `&rest` parameter to that list. So:

``` > (defun foo (x &rest y) y) FOO > (foo 3) NIL > (foo 4 5 6) (5 6) ```

Finally, you can give your function another kind of optional argument called a keyword argument. The caller can give these arguments in any order, because they're labelled with keywords.

``` > (defun foo (&key x y) (cons x y)) FOO > (foo :x 5 :y 3) (5 . 3) > (foo :y 3 :x 5) (5 . 3) > (foo :y 3) (NIL . 3) > (foo) (NIL) ```

An `&key` parameter can have a default value too:

``` > (defun foo (&key (x 5)) x) FOO > (foo :x 7) 7 > (foo) 5 ```   