宏的存在让我们能够创造出新语法。我们先看一下内置的宏。
1.when
when的语法如下:
(when (condition)
body )
例子:
#!/usr/bin/env clisp
(defun foo (x y)
;when宏可以执行满足条件的多个表达式
(when ( > x y)
(format t "~d is lager than ~d." x y)
(print "this is a print line.")))
(foo 20 10)
2.unless
unless的语法与when类似,只是condition为假时才执行表达式
语法如下:
(unless (condition)
body)
例子:
#!/usr/bin/env clisp
(defun foo (x y)
;测试为假时执行
(unless (> x y)
(print "This is a print line.")))
(foo 10 20)
3.cond
cond宏可以测试多个condition,用以多个判断分支的丑陋语法。
语法如下:
(cond
(condition1 form1)
(condition2 form2)
(condition3 form3))
各分支按顺序求值,直到其中的一个求值为真。然后对该分支中的其他表达式求值,并将做后一个表达式的结果作为返回值返回。
例子:
#!/usr/bin/env clisp
(defun foo (x y)
(cond
((> x y) (format t "~d is lager than ~d" x y) (- x y))
((< x y) (format t "~d is less than ~d" x y) (+ x y))
((= x y) (format t "~d is equal with ~d" x y) (* x y))
)
)
;调用foo并打印返回值
(print (foo 10 20))
4.not or and
这三个宏都是用来测试condition的,很好理解,暂不写例子了。
5.循环
(1).dolist
语法如下:
(dolist (item list-form)
body-form*)
例子如下:
#!/usr/bin/env clisp
(defun foo (int_list)
(dolist (item int_list)
(if (> item 25)
(return))
(print item)))
(foo (list 10 20 30))
(2).dotimes
语法如下:
(dotimes (var count-form)
body-form*)
例子,我们写一个打印x*y的乘法表:
#!/usr/bin/env clisp
(defun foo (x y)
(dotimes (x 9)
(dotimes (y 9)
(format t "~3d " (* (1+ x) (1+ y)))
)
(format t "~%")
)
)
(foo 9 9)
结果如下:
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
(3)do
do宏可以实现多路推进并可定义步长,不过理解起来有些许晦涩,其语法如下
(do (variable-definition*)
(end-test-form result-form*)
statement*)
其中variable-definition格式如下:
(var init-form step-form)
当所有的step-form被求值之后 var才能被求值。如下是一个求第n项斐波那契数的函数:
#!/usr/bin/env clisp
(defun foo(end)
(do ((n 0 (1+ n)) ;(var init step)
(cur 0 next) ;(var init step)
(next 1 (+ cur next))) ;(var init step)
((= end n) cur) ;(end-test-form result-form)
)
)
(print (foo 10))