📄 00000004.htm
字号:
<BR>><I> (setq a 3) </I><BR>3 <BR>><I> (cond </I><BR> ((evenp a) a) ;if a is even return a <BR> ((> a 7) (/ a 2)) ;else if a is bigger than 7 return a/2 <BR> ((< a 5) (- a 1)) ;else if a is smaller than 5 return a-1 <BR> (t 17) ;else return 17 <BR> ) <BR>2 <BR> <BR>If the action in the selected cond clause is missing, cond returns what <BR>the condition evaluated to: <BR> <BR>><I> (cond ((+ 3 4))) </I><BR>7 <BR> <BR>Here's a clever little recursive function which uses cond. You might be <BR>interested in trying to prove that it terminates for all integers x at <BR>least 1. (If you succeed, please publish the result.) <BR> <BR>><I> (defun hotpo (x steps) ;hotpo stands for Half Or Triple Plus One </I><BR> (cond <BR> ((= x 1) steps) <BR> ((oddp x) (hotpo (+ 1 (* x 3)) (+ 1 steps))) <BR> (t (hotpo (/ x 2) (+ 1 steps))) <BR> ) ) <BR>A <BR>><I> (hotpo 7 0) </I><BR>16 <BR> <BR>The LISP case statement is like a C switch statement: <BR> <BR>><I> (setq x 'b) </I><BR>B <BR>><I> (case x </I><BR> (a 5) <BR> ((d e) 7) <BR> ((b f) 3) <BR> (otherwise 9) <BR> ) <BR>3 <BR> <BR>The otherwise clause at the end means that if x is not a, b, d, e, or <BR>f, the case statement will return 9. <BR> <BR> <BR> <BR>Iteration <BR> <BR>The simplest iteration construct in LISP is loop: a loop construct <BR>repeatedly executes its body until it hits a return special form. For <BR>example, <BR> <BR>><I> (setq a 4) </I><BR>4 <BR>><I> (loop </I><BR> (setq a (+ a 1)) <BR> (when (> a 7) (return a)) <BR> ) <BR>8 <BR>><I> (loop </I><BR> (setq a (- a 1)) <BR> (when (< a 3) (return)) <BR> ) <BR>NIL <BR> <BR>The next simplest is dolist: dolist binds a variable to the elements of <BR>a list in order and stops when it hits the end of the list. <BR> <BR>><I> (dolist (x '(a b c)) (print x)) </I><BR>A <BR>B <BR>C <BR>NIL <BR> <BR>Dolist always returns nil. Note that the value of x in the above <BR>example was never nil: the NIL below the C was the value that dolist <BR>returned, printed by the read-eval-print loop. <BR> <BR>The most complicated iteration primitive is called do. A do statement <BR>looks like this: <BR> <BR>><I> (do ((x 1 (+ x 1)) </I><BR> (y 1 (* y 2))) <BR> ((> x 5) y) <BR> (print y) <BR> (print 'working) <BR> ) <BR>1 <BR>WORKING <BR>2 <BR>WORKING <BR>4 <BR>WORKING <BR>8 <BR>WORKING <BR>16 <BR>WORKING <BR>32 <BR> <BR>The first part of a do specifies what variables to bind, what their <BR>initial values are, and how to update them. The second part specifies a <BR>termination condition and a return value. The last part is the body. A <BR>do form binds its variables to their initial values like a let, then <BR>checks the termination condition. As long as the condition is false, it <BR>executes the body repeatedly; when the condition becomes true, it <BR>returns the value of the return-value form. <BR> <BR>The do* form is to do as let* is to let. <BR> <BR> <BR> <BR>Non-local Exits <BR> <BR>The return special form mentioned in the section on iteration is an <BR>example of a nonlocal return. Another example is the return-from form, <BR>which returns a value from the surrounding function: <BR> <BR>><I> (defun foo (x) </I><BR> (return-from foo 3) <BR> x <BR> ) <BR>FOO <BR>><I> (foo 17) </I><BR>3 <BR> <BR>Actually, the return-from form can return from any named block -- it's <BR>just that functions are the only blocks which are named by default. You <BR>can create a named block with the block special form: <BR> <BR>><I> (block foo </I><BR> (return-from foo 7) <BR> 3 <BR> ) <BR>7 <BR> <BR>The return special form can return from any block named nil. Loops are <BR>by default labelled nil, but you can make your own nil-labelled blocks: <BR> <BR>><I> (block nil </I><BR> (return 7) <BR> 3 <BR> ) <BR>7 <BR> <BR>Another form which causes a nonlocal exit is the error form: <BR> <BR>><I> (error "This is an error") </I><BR>Error: This is an error <BR> <BR>The error form applies format to its arguments, then places you in the <BR>debugger. <BR> <BR> <BR> <BR>Funcall, Apply, and Mapcar <BR> <BR>Earlier I promised to give some functions which take functions as <BR>arguments. Here they are: <BR> <BR>><I> (funcall #'+ 3 4) </I><BR>7 <BR>><I> (apply #'+ 3 4 '(3 4)) </I><BR>14 <BR>><I> (mapcar #'not '(t nil t nil t nil)) </I><BR>(NIL T NIL T NIL T) <BR> <BR>Funcall calls its first argument on its remaining arguments. <BR> <BR>Apply is just like funcall, except that its final argument should be a <BR>list; the elements of that list are treated as if they were additional <BR>arguments to a funcall. <BR> <BR>The first argument to mapcar must be a function of one argument; mapcar <BR>applies this function to each element of a list and collects the <BR>results in another list. <BR> <BR>Funcall and apply are chiefly useful when their first argument is a <BR>variable. For instance, a search engine could take a heuristic function <BR>as a parameter and use funcall or apply to call that function on a <BR>state description. The sorting functions described later use funcall <BR>to call their comparison functions. <BR> <BR>Mapcar, along with nameless functions (see below), can replace many <BR>loops. <BR> <BR> <BR> <BR>Lambda <BR> <BR>If you just want to create a temporary function and don't want to <BR>bother giving it a name, lambda is what you need. <BR> <BR>><I> #'(lambda (x) (+ x 3)) </I><BR>(LAMBDA (X) (+ X 3)) <BR>><I> (funcall * 5) </I><BR>8 <BR> <BR>The combination of lambda and mapcar can replace many loops. For <BR>example, the following two forms are equivalent: <BR> <BR>><I> (do ((x '(1 2 3 4 
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -