# LISP - 函式

## LISP函式定義

• 函式名稱

• 函式的引數

• 函式的體

defun語法是：

```(defun name (parameter-list)
"Optional documentation string."
body)```

```(defun averagenum (n1 n2 n3 n4)
(/ ( + n1 n2 n3 n4) 4))
(write(averagenum 10 20 30 40))```

`25`

```(defun area-circle(rad)
"Calculates area of a circle with given radius"
(terpri)
(area-circle 10)```

• 可以提供一個空的列表作為引數，這意味著函式沒有引數，該列表是空的，表示為()。

• LISP還允許可選，多個和關鍵字引數。

• 文件字串描述了函式的目的。它與函式名相關聯，並且可以使用文件函式來獲得。

• 函式的主體可以包含任意數量的Lisp表示式。

• 在主體內的最後一個表示式的值返回函式的值。

• 還可以使用返回 - 從特殊的運算子函式返回一個值。

## 可選引數

```(defun show-members (a b &optional c d) (write (list a b c d)))
(show-members 1 2 3)
(terpri)
(show-members 'a 'b 'c 'd)
(terpri)
(show-members 'a 'b)
(terpri)
(show-members 1 2 3 4)
```

```(1 2 3 NIL)
(A B C D)
(A B NIL NIL)
(1 2 3 4)```

## 其餘部分引數

```(defun show-members (a b &rest values) (write (list a b values)))
(show-members 1 2 3)
(terpri)
(show-members 'a 'b 'c 'd)
(terpri)
(show-members 'a 'b)
(terpri)
(show-members 1 2 3 4)
(terpri)
(show-members 1 2 3 4 5 6 7 8 9)
```

```(1 2 (3))
(A B (C D))
(A B NIL)
(1 2 (3 4))
(1 2 (3 4 5 6 7 8 9))```

## 關鍵字引數

```(defun show-members (&key a b c d ) (write (list a b c d)))
(show-members :a 1 :c 2 :d 3)
(terpri)
(show-members :a 'p :b 'q :c 'r :d 's)
(terpri)
(show-members :a 'p :d 'q)
(terpri)
(show-members :a 1 :b 2)
```

```(1 NIL 2 3)
(P Q R S)
(P NIL NIL Q)
(1 2 NIL NIL)```

## 從函式返回的值

```(defun add-all(a b c d)
(+ a b c d))
(setq sum (add-all 10 20 30 40))
(write sum)
(terpri)
(write (add-all 23.4 56.7 34.9 10.0))```

```100
125.0```

```(defun myfunc (num)
(return-from myfunc 10)
num)
(write (myfunc 20))```

`10`

```(defun myfunc (num)
(return-from myfunc 10)
write num)
(write (myfunc 20))```

`10`

## lambda函式

LISP允許編寫評估計算在程式中遇到的匿名函式。這些函式被稱為Lambda函式。

`(lambda (parameters) body)`

lambda形式可以不進行評估計算，它必須出現只有在LISP希望找到一個函式。

```(write ((lambda (a b c x)
(+ (* a (* x x)) (* b x) c))
4 2 9 3))```

`51`

## 對映函式

`(write (mapcar '1+  '(23 34 45 56 67 78 89)))`

`(24 35 46 57 68 79 90)`

```(defun cubeMylist(lst)
(mapcar #'(lambda(x) (* x x x)) lst))
(write (cubeMylist '(2 3 4 5 6 7 8 9)))
```

`(8 27 64 125 216 343 512 729)`

`(write (mapcar '+ '(1 3 5 7 9 11 13) '( 2 4 6 8)))`

`(3 7 11 15)`