Ngôn ngữ lập trình Chương VIII: Lập trình hàm
84
Biểu thức
Biểu thức là một nguyên tử hoặc một danh sách. Biểu thức luôn có một giá trị mà việc
định trị nó theo nguyên tắc sau:
• Nếu biểu thức là một số, thì giá trị của biểu thức là giá trị của số đó.
Ví dụ:
> 25
= 25
• Nếu biểu thức là một ký hiệu thì giá trị của biểu thức có thể là
- Được xác định trước bởi LISP (chẳng hạn t có giá trị là T (TRUE) và nil có
giá trị là NIL một danh sách rỗng) hoặc
- Một giá trị dữ liệu của người sử dụng hoặc trong chương trình được gán cho
một biến. Biến không cần phải khai báo.
Ví du:
> (setq a 3) ; Gán số 3 cho biến có tên a
= 3
> a ; hỏi giá trị của ký hiệu “a”
= 3
• Nếu biểu thức là một danh sách có dạng (E
0
E
1
E
n
) thì giá trị của biểu thức được
xác định theo cách sau đây:
- Phần tử đầu tiên E
0
phải là một hàm đã được LISP nhận biết.
- Các phần tử E
1
, E
2
, , E
n
được định trị tuần tự từ trái sang phải. Giả sử ta có
các giá trị tương ứng là V
1
, V
2
, , V
n
- Hàm E
0
được áp dụng cho các đối V
1
, V
2
, , V
n
. Giá trị của hàm E
0
chính là
giá trị của biểu thức.
Ví dụ
> (+ 5 3 6)
= 14
> ( + 4 (+ 3 5))
= 12
- Chú ý: Nếu biểu thức dùng hàm QUOTE hoặc dấu nháy đơn sẽ không được
đánh giá
Ví dụ:
> ‘(+ 1 2)
= (+ 1 2)
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
.
Ngôn ngữ lập trình Chương VIII: Lập trình hàm
85
8.3.3 Các hàm
Một chương trình của LISP là một hàm hoặc một hàm hợp. Các hàm có thể do LISP
định nghĩa trước hoặc do lập trình viên tự định nghĩa.
Một số hàm định nghĩa trước
• Các hàm số học: +, -, *, /, 1+, 1-, MOD, SQRT tác động lên các biểu thức số và
cho kết quả là một số.
Ví dụ:
> (+ 5 6 2)
= 13
> (- 8 3)
= 5
> (- 8 3 1)
= 4
>(1+ 5) ; Tương đương (+ 5 1)
= 6
> (1- 5) ; Tương đương (- 5 1)
= 4
>(MOD 14 3)
= 2
>(sqrt 9) ; Lấy căn bậc hai của 9
= 3
• Các hàm so sánh các số <, >, <=, >=, = và /=, cho kết quả là T hoặc NIL
Ví dụ:
>(< 4 5)
= T
>(> 4 (* 2 3))
= NIL
• (EQ s1 s2) so sánh xem hai ký hiệu s1 và s2 có giống nhau hay không?
Ví dụ:
>(eq ‘tuong ‘tuong)
= T
>(eq ‘tuong ‘duong)
= NIL
>(eq ‘5 5 )
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
.
Ngôn ngữ lập trình Chương VIII: Lập trình hàm
86
= T
• (EQUAL o1 o2) so sánh xem đối tượng bất kỳ o1 và o2 có giống nhau hay
không?
Ví dụ:
>(equal ‘(a b c) ‘(a b c))
= T
>(equal ‘(a b c) ‘( b a c))
= NIL
>(equal ‘a ‘a)
= T
• Các hàm thao tác trên danh sách: CAR, CDR, CONS và LIST
- (CAR L) nhận vào danh sách L, trả về phần tử đầu tiên của L.
Ví du:
> (CAR '(1 2 3))
= 1
> (CAR 3)
Error: bad argument type - 3
>(CAR nil)
= NIL
> (CAR '((a b) 1 2 3))
= (A B)
- (CDR L) nhận vào danh sách L, trả về một danh sách bằng phần còn lại của
danh sách L sau khi bỏ đi phần tử đầu tiên.
Ví dụ:
>(cdr '(1 2 3))
= (2 3)
>(cdr 3)
Error: bad argument type - 3
>(cdr nil)
= NIL
>(cdr '(1))
= NIL
>(CAR (CDR ‘(a b c)))
= B
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
.
Ngôn ngữ lập trình Chương VIII: Lập trình hàm
87
- Viết gộp các hàm: Ta có thể dùng hàm C A/D R để kết hợp nhiều CAR và
CDR (có thể thay thế việc lồng nhau tới 4 cấp)
Ví du:
(CADR ‘(a b c))
= B
- (CONS x L) nhận vào phần tử x và danh sách L, trả về một danh sách, có
được bằng cách thêm phần tử x vào đầu danh sách L
Ví du:
>(CONS 3 '(1 2 3))
= (3 1 2 3)
>(CONS 3 nil)
= (3)
>(CONS '(a b) '(1 2 3))
= ((A B) 1 2 3)
- (LIST E
1
E
2
E
n
) nhận vào n biểu thức E
1
, E
2
, , E
n
,
trả về danh sách bao
gồm n phần tử V
1
, V
2
, , V
n
,
trong đó V
i
là giá trị của biểu thức E
i
(i=1 n) .
Ví du:
>(list 1 2)
= (1 2)
>(list 'a 'b)
= (A B)
>(list 'a 'b (+ 2 3 5))
= (A B 10)
• Các vị từ kiểm tra
- (ATOM a) xét xem a có phải là một nguyên tử.
- (NUMBERP n) xét xem n có phải là một số.
- (LISTP L) xét xem L có phải là một danh sách.
- (SYMBOLP S) xét xem S có phải là một ký hiệu.
- (NULL L) nhận vào 1 danh sách L. Nếu L rỗng thì trả về kết quả là T,
ngược lại thì trả về kết quả là NIL.
Ví du:
>(atom 'a)
= T
>(numberp 4)
= T
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
.
Ngôn ngữ lập trình Chương VIII: Lập trình hàm
88
>(symbolp 'a)
= T
>(listp '(1 2))
= T
>(symbolp NIL)
= T
>(listp NIL)
= T
>(null NIL)
= T
>(null ‘(a b))
= NIL
>(null 10)
= NIL
• Các hàm logic AND, OR và NOT
- (AND E
1
E
2
E
n
) nhận vào n biểu thức E
1
, E
2
, E
n
. Hàm AND định trị các
biểu thức E
1
E
2
E
n
từ trái sang phải. Nếu gặp một biểu thức là NIL thì
dừng và trả về kết quả là NIL. Nếu tất cả các biểu thức đều khác NIL thì trả
về giá trị của biểu thức E
n
.
Ví dụ:
>(AND (> 3 2) (= 3 2) (+ 3 2))
= NIL
>(AND (> 3 2) (- 3 2) (+ 3 2))
= 5
- (OR E
1
E
2
E
n
) nhận vào n biểu thức E
1
, E
2
, E
n
. Hàm OR định giá các
biểu thức E
1
E
2
E
n
từ trái sang phải. Nếu gặp một biểu thức khác NIL thì
dừng và trả về kết quả là giá trị của biểu thức đó. Nếu tất cả các biểu thức
đều là NIL thì trả về kết quả là NIL.
Ví du:
>(OR (= 3 2) (+ 2 1) (list 1 2))
= 3
>(OR (= 2 1) (Cdr ‘(a) ) (listp 3 ))
= NIL
- (NOT E) nhận vào biểu thức E. Nếu E khác NIL thì trả về kết quả là NIL,
ngược lại thì trả về kết quả là T.
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
.