Program Structure 笔记4 (数据处理形式以及let语句)
(作者:colinboy Email:cybbh@163.com) 2008.5.2 V1
(内容难免出现错误或一些专业词汇使用不当,只是个人笔记,能理解总体内容就好)
数据处理形式
1.转换(逐个处理) EVERY
将输入数据根据某种转换规则转换
(define (double sent)
(if (empty? sent)
'()
(se (first sent) (first sent) (double (bf sent)))))
(double '(boy apple cat int)) --> (boy boy apple apple cat cat int int)
在scheme中用every函数来完成转换:
(every (lambda (wd) (se wd wd)) '(my name)) --> (my my name name)
2.选择 KEEP
根据条件,选择符合条件的输入数据
(define (starts sent)
(cond ((empty? sent) '())
((equal? (first (first sent)) 's)
(se (first sent) (starts (bf sent))))
(else (starts (bf sent)))))
(starts '(skill school job my sky hat)) --> (skill school sky)
在scheme中用keep函数来完成选择:
(keep (lambda (num) (> num 5)) '(1 2 3 4 5 6 7 8)) --> (6 7 8)
3.堆积 ACCUMULATE
把输入的数据按照某种方法堆积成一个数据
(accumulate + 0 '(1 2 3 4 5)) --> 15
一个解一元二次方程的例子
(define (roots a b c)
(define (roots1 d)
(se (/ (+ (- b) d) (* 2 a))
(/ (- (- b) d) (* 2 a))))
(roots1 (sqrt (- (* b b) (* 4 a c)))))
(roots 2 10 6) --> (-0.697224362268005 -4.30277563773199)
上面例子我们可以转换成使用lambda语句来构建
(define (roots a b c)
((lambda (d)
(se (/ (+ (- b) d) (* 2 a))
(/ (+ (- b) d) (* 2 a))))
(sqrt (- (* b b) (* 4 a c)))))
显然用lambda语句是个错误的决定,让我们的代码很难读.如果我们能创建几个存在于roots中的局部变量,会使我们的程序更容易阅读,下面将用到let语句创建局部变量.
(define (roots a b c)
(let ((d (sqrt (- (* b b) (* 4 a c)))))
(se (/ (+ (- b) d) (* 2 a))
(/ (- (- b) d) (* 2 a)))))
(roots 2 10 6) --> (-0.697224362268005 -4.30277563773199)
let语句是一种特殊形式,是lambda语句的另一种表现形式.
let = lambda + 调用()
例如
(let ((a 7)
(b (+ a 3)))
(* a b))
上面代码初看来也许会觉得因为a等于7,上面的b会等于10,但是却是错误的,为什么呢? 因为let是lambda的另一种表现形式,我们把此let语句转换成lambda语句就会明白了.
((lambda (a b) (* a b)) 7 (+ a 3))
显然(+ a 3)中的a是一个全局变量,而lambda (a b)中的a是一个形式参数,它们表示的是不同的变量.