Common Lisp入門筆記(四)函數

摘自 《Lisp語言- 陳光喜》

一、函數

1、defun

Common Lisp中定義函數使用defun來完成。通常需要3個以上的參數:函數名、參數表、函數體。例如:

>(defun area(r)

               (* PI   r   r))

>AREA

在Common Lisp中,每個函數的地位都是一樣的,沒有所謂的main函數。函數調用的求值規則就是表達式求值規則:

首先對每個參數從左到右求值;其次將這些已經求值的參數作爲運算符函數的參數進行函數調用求值;函數的返回值由該函數最後一個求值表達式的值給出。


例1,定義求笛卡爾積的函數

CL-USER> (defun discarets(list1 list2)
  (let ((a nil)(rst nil))
    (dolist (v list1 rst)
      (dolist (u list2)
(setf a (list u v)
      rst (cons a rst))))))
DISCARETS


2、函數對象

在 Lisp 中,函數與符號、表、字符串等都是對象。Lisp 提供的 function 函數可以給出函數的關聯屬性。

例如:

CL-USER> (function eq)
#<Compiled-function EQ #x100097DEF>


function 函數可以簡寫爲#’。例如,
CL-USER> #' cons
#<Compiled-function CONS #x1000D88DF>


函數 apply 和 funcall 可以以函數作爲參數。
例如:
> (apply #'area '(2))
12.5663706143592
> (apply #'* '(1 2 3 4))
24
> (funcall #'area 2)
12.5663706143592
> (funcall #'* 1 2 3 4)
24



二、lambda表達式

defun 用於創建一個函數,並給出一個函數名。事實上,在 Lisp 中函數未必需要函數名。早期版本的 Lisp 提供lambda 表達式來實現函數定義。
Lambda 表達式是一個表,包含符號 lambda,然後是一個參數表,最後是 0 個或多個表達式的函數體。在 Lisp 中採用如下形式描述一個函數: (lambda (p1p2 ... pn) e) 其中, pi爲原子,在函數中稱之爲參數,e 是表達式,也就是函數體。
調用一個函數的方式如下:((lambda (p1p2 ... pn) e) a1a2 ... an)其中 ai爲表達式,按照慣例稱爲實參。整個函數的調用過程如下:每一個表達式 ai(實參)先求值,然後再將這些實參代入 e 中求值,最後的結果即爲整個表達式的返回值。


小結:
1) Lisp 是交互式的程序設計語言。只有 7 個基本操作符。在 toplevel 環境下用戶輸入的表達式都將被求值。
2) Lisp 沒有函數與程序之分。函數由前綴表達式組成。表達式可以是原子,也可以是表。通常表的第一個元素是操作符,其餘元素是它的參數。前綴表達式意味着參數個數是任意的。
3) 函數調用時參數表從左至右求值。Quote 將參數原樣返回。
4) Lisp 程序就是表,容易實現寫程序的程序。
5) if 和 cond 用於條件表達式。nil 是假,從邏輯上講,不是 nil 的都是真。
6) do 和 dolist 用於循環。Defun 用於定義用戶函數。函數用 lambda 表達式來實現。函數也是Lisp 對象,可以作爲函數的參數。
7) 遞歸函數是調用自身的函數,它是 Lisp 的基本特徵。遞歸類似於數學歸納法。
8) 基本輸入輸出用 read 和 format 實現,可以使用 let 定義局部變量;defparameter 定義全局變量;setf 用於變量賦值




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章