#lang racket
;(h i (lambda (hi) ...)) We assume that hi is
;the result of applying (h i). Then, we drop in everything else that
;has to be done to replace the ...:
;(f (g (h i) (j l)))
;becomes
;(h i (lambda (hi) (f (g hi (j l)))))
;rember方法
;普通方式
(define rember8
(lambda (ls)
(cond
[(null? ls) '()]
[(= (car ls) 8) (cdr ls)]
[else (cons (car ls) (rember8 (cdr ls)))])))
(rember8 '(1 2 8 3 4 6 7 8 5))
;第一步,参数中添加一个k
;whenever we see a lambda in the code we want to CPS, we
;have to add an argument, and then process the body
;(define rember8
; (lambda (ls k)
; (cond
; [(null? ls) '()]
; [(= (car ls) 8) (cdr ls)]
; [else (cons (car ls) (rember8 (cdr ls)))])))
;第二步,不要为小事费力
;Second rule: "Don't sweat the small stuff!"
;Small stuff is stuff we know will terminate right away.
;Don't sweat the small stuff if we know it will be evaluated.
;Don't sweat the small stuff if it *might* be evaluated, but instead
;pass it to k.
;cond的第一个分支
;(null? ls)为will terminate right away,所以不用管
;'()为*might* be evaluated,所以传递给k
;(define rember8
; (lambda (ls k)
; (cond
; [(null? ls) (k '())]
; [(= (car ls) 8) (cdr ls)]
; [else (cons (car ls) (rember8 (cdr ls)))])))
;cond的第二个分支,传递给k
;(define rember8
; (lambda (ls k)
; (cond
; [(null? ls) (k '())]
; [(= (car ls) 8) (k (cdr ls))]
; [else (cons (car ls) (rember8 (cdr ls)))])))
;cond的第三个分支,需要创建一个新的continuation
;(define rember8
; (lambda (ls k)
; (cond
; [(null? ls) (k '())]
; [(= (car ls) 8) (k (cdr ls))]
; [else (rember8 (cdr ls) (lambda (x) (cons (car ls) x)))])))
;将新的continuation pass to k
;将新的continuation与老的continuation即k,连接起来
(define rember8-cps
(lambda (ls k)
(cond
[(null? ls) (k '())]
[(= (car ls) 8) (k (cdr ls))]
[else (rember8-cps (cdr ls) (lambda (x) (k (cons (car ls) x))))])))
;第四步,确定k为什么
;当ls为空list的时候,普通rember8的返回值应该为空list,即cps的rember8中(k '())的值为'(),所以k为identity function
(rember8-cps '(1 2 8 3 4 6 7 8 5) (lambda (x) x))
;普通multirember8
(define multirember8
(lambda (ls)
(cond
[(null? ls) '()]
[(= (car ls) 8) (multirember8 (cdr ls))]
[else (cons (car ls) (multirember8 (cdr ls)))])))
(multirember8 '(1 2 8 3 4 6 7 8 5))
;转换为cps的形式
(define multirember8-cps
(lambda (ls k);参数添加k
(cond
[(null? ls) (k '())];返回值传递给k
[(= (car ls) 8) (multirember8-cps (cdr ls) k)] ;透传函数
[else (multirember8-cps (cdr ls) (lambda (x)
(k (cons (car ls) x))))])));添加一个新的continuation,并传递给k
;最后一步,确定k的函数
;ls为空时,返回值为空list,所以k为(lambda (v) v)
(multirember8-cps '(1 2 8 3 4 6 7 8 5) (lambda (v) v))
;非尾递归
(define fact
(lambda (n)
(cond
[(zero? n) 1]
[else (* (fact (- n 1)) n)])))
(fact 5)
;尾递归
;;aps
;;accumulator-passing style
(define fact-aps
(lambda (n acc)
(cond
[(zero? n) acc]
[else (fact-aps (sub1 n) (* acc n))])))
(define fact2
(lambda (n)
(fact-aps n 1)))
(fact2 5)
;;cps
(define fact-cps
(lambda (n k)
(cond
[(zero? n) (k 1)] ;;当n为0的时候,我们给continuation的东西为1
[else (fact-cps (sub1 n) ;;我们需要创建一个新的continuation,代表剩下的计算
(lambda (v) ;;此时,我们给到continuation的东西为什么,新的continuation传递给老的continuation k
(k (* v n))))])))
(fact-cps 5 (lambda (v) v))
(fact-cps 5 (lambda (v) (* 3 v)))
01-18
143
08-04
08-04