一、问题的定义和作用
1.定义:Peter J. Landin 在1964年将术语 闭包 定义为一种包含 环境成分 和 控制成分的实体,用于在他的SECD 机器上对表达式求值。
2. 作用:通过构造出某种同类的东西,支持任意和无限次的复合。
实践一
上面的图形(P(n))可以通过这种方法构造:首先在右边画一个长方形(Rn),然后左边是由两个上下临界的图形(P(n-1)/P(n-1))组成的,每个图形(P(n-1))是先画一个长方形,然后左边是两个上下临界的图形组成的
可以这样使用数学公式表示
P(n)=(P(n-1)/P(n-1))|Rn P(n-1)=(1/4)P(n),(/表示上下临界,|表示左右临界)
P0为小正方行
下面是产生该图形的代码:
#lang slideshow
(define MinSize 5)
(define (picture-2 n)
(let ((wid (* (expt 2 n) MinSize)))
(if (= n 0)
(rectangle wid wid)
(hc-append (vc-append (picture-2 (- n 1)) (picture-2 (- n 1))) (rectangle (/ wid 2) wid)))))
(picture-2 4)
drracket中图形库slideshow是闭包的,我们可以将任意两个图形组合成一个新的图形,然后新的图形组合成更复杂的图形。
实践二
上面这个图形更加复杂,首先我们将它分成4份
其中R(n-1)为T(n-1)旋转90度所得
Pn=(P(n-1)/R(n-1))|(T(n-1)/Sn), P(n-1)=1/4(P(n)) P0为正方形
T(n-1)的画法很多,可以将其看作两个长方形区域组成(K(n-1)|K(n-1))
K(n)=(K(n-1)|K(n-1)/S(n-1) (S表示正方形 S(n-1)=1/4(S(n)),/表示上下临界,|表示左右临界)
这样就可以写出下面的代码
(define (first-splite-second-half combine splite n f1 f2)
(let ((wid (* (expt 2 n) MinSize)))
(if (= n 0)
(rectangle wid wid)
(combine (splite (first-splite-second-half combine splite (- n 1) f1 f2)
(first-splite-second-half combine splite (- n 1) f1 f2))
(rectangle (* wid f1) (* wid f2))))))
(define (top-splite-1 n)
(first-splite-second-half vc-append hc-append n 1 1))
(define (left-splite-1 n)
(first-splite-second-half hc-append vc-append n 1 1))
(define (corner-splite-left-top n)
(let ((wid (* (expt 2 n) MinSize)))
(if (= n 0)
(rectangle wid wid)
(let ((up (top-splite-1 (- n 1)))
(left (left-splite-1 (- n 1))))
(let ((top-right (hc-append up up))
(bottom-left (vc-append left left))
(corner (corner-splite-left-top (- n 1))))
(vc-append (hc-append corner top-right)
(hc-append bottom-left (rectangle wid wid))))))))
可能是slideshow自身的原因(计算旋转会有一些误差,当把left-splite-1改为top-splite-1旋转90度,则画出的图形有一些瑕疵
(define (top-splite-1 n)
(first-splite-second-half vc-append hc-append n 1 1))
;(top-splite-1 4)
(define (left-splite-1 n)
;(first-splite-second-half hc-append vc-append n 1 1))
(rotate (top-splite-1 n) (/ pi 2)))
实践三
如果将上面得到的图形分别旋转90 180 270, 然后拼成一个大正方形,就是这样的
(define (c2 n) (corner-splite-left-top n))
(define (c3 n) (rotate (c2 n) (/ pi 2)))
(define (c4 n) (rotate (c3 n) (/ pi 2)))
(define (c5 n) (rotate (c4 n) (/ pi 2)))
(define (whole n)
(hc-append
(vc-append (c2 n) (c3 n))
(vc-append (c5 n) (c4 n))))
(参考SICP)