use*_*ond 9 scheme programming-languages functional-programming racket
(defun triangle-using-cond (number)
(cond
((<= number 0) 0) ; 1st
((= number 1) 1) ; 2nd
((> number 1) ; 3rd
;; 4th
(+ number
(triangle-using-cond (1- number))))))
Run Code Online (Sandbox Code Playgroud)
关于康德的事情
我无法区分的一件事是cond与函数有什么不同!
soe*_*ard 10
函数调用(e0 e1 e2)就像这样评估
1. e0 is evaluated, the result is (hopefully) a function f
2. e1 is evaluated, the result is a value v1
3. e2 is evaluated, the result is a value v2
4. The function body of `f` is evaluated in an environment in which
the formal parameters are bound to the values `v1` and `v2`.
Run Code Online (Sandbox Code Playgroud)
请注意,在激活函数体之前,将评估所有表达式e0,, e1和e2.
这意味着函数调用 (foo #t 2 (/ 3 0))会在(/ 3 0)评估时导致错误- 在将控制权移交给正文之前foo.
现在考虑特殊形式if.在(if #t 2 (/ 3 0))表达式#t中进行求值,并且由于值为非假,所以计算第二个表达式2,结果值为2.这里(/ 3 0)永远不会计算.
如果相反if是一个函数,则表达式#t,2以及,(/ 3 0)被被激活体前评估.现在(/ 3 0)会产生错误 - 即使不需要表达式的值.
简而言之:在将控件传递给函数体之前,函数调用将始终评估所有参数.如果不评估某些表达式,则需要特殊形式.
这里if和cond是形式的例子,不评估所有的子表达式-因此他们,他们需要特殊形式.
如果cond不是特殊形式,那么表达式:
((> number 1) ;;3rd
(+ number (triangle-using-cond (1- number))))
Run Code Online (Sandbox Code Playgroud)
会导致:
无限循环因为triangle-using-cond会通过尾调用递归调用自身 (triangle-using-cond (1- number)).
或者,最后一个表达式将尝试应用该值#f或#t作为函数(在类型2 Lisp中,例如ANSI Common Lisp是可能的,但在类型1 Lisp中不可能,例如Racket或Scheme)并产生错误.
什么使得cond一个特殊的形式是它的参数被懒惰地评估,而Scheme或Common Lisp中的函数急切地评估它们的参数.