let,let*和letrec
在scheme中.let,let*和letrec的形式均写做:(id val-expr).即:
(let ([id val-expr] ...) body ...+),(let* ([id val-expr] ...) body ...+),(letrec ([id val-expr] ...) body ...+)
三者的不同在于,对id及val-expr的运算顺序不同.由此导致的结果也不同.
在let中.先依此所有的计算val-expr.在依此所有的计算id.
在let*中.先计算一个val-expr,将其赋值给id.在进行下一个(id val-expr)的计算.
在letrec中.id首先均为undefined.然后计算所有的val-expr.
由此:
(define foo 5) ;; foo 現在取值 5 (let ((foo 10)) ;; foo 現在取值 10 ) ;; foo 現在取值 5
这三者的区别在于,let
所绑定的变量仅在它的区块内有效,而let*
所绑定的变量可以在以下的绑定中使用,例如,
(let* ((var1 10) (var2 (+ var1 5))) var1) ;; 返回 15 ;; 如果僅使用 let,程式會出錯。
letrec
所绑定的变量可以互相引用。因此,letrec
通常被用于双重递归:
(letrec ((female (lambda(n) (if (= n 0) 1 (- n (male (female (- n 1))))))) (male (lambda(n) (if (= n 0) 0 (- n (female (male (- n 1)))))))) (display "i male(i) female(i)")(newline) (do ((i 0 (+ i 1))) ((> i 8) #f) (display i) (display " ")(display (male i))(display " ")(display (female i)) (newline)))
(via wikipedia)
同时 剥去语法糖.
(let ((x 1))
(print x))
就是
((lambda (x) (print x)) 1)
(letrec ((fact (lambda (x)
(if (= x 1)
x
(* x (fact (- x 1)))))))
(fact 5))
是
((lambda (fact x)
(fact x fact))
(lambda (x fact)
(if (= x 1)
x
(* x (fact (- x 1) fact))))
5)
也可以这样:
(letrec ((f (lambda ...))) ...)
就是
(let ((f <undefined>)) (set! f (lambda ...)) ...)
2024年1月16日 17:28
It was thinking about whether I could utilize this review on my other site, I will connect it back to your site though.Great Thanks.
2024年1月16日 17:29
It was thinking about whether I could utilize this review on my other site, I will connect it back to your site though.Great Thanks.